Per evitare che script dannosi utilizzino in modo illecito API sensibili come i popup, schermo intero e così via, i browser controllano l'accesso a queste API tramite dell'attivazione. L'attivazione utente è lo stato di una sessione di navigazione in relazione alle azioni dell'utente: la generazione implica in genere che l'utente sta interagendo con la pagina o ha completato un'interazione dalla pagina caricamento. Gesto dell'utente è un termine popolare ma fuorviante per la stessa idea. Per Ad esempio, un gesto di scorrimento o di scorrimento dell'utente non attiva la pagina, pertanto non è, dal punto di vista dello script, un'attivazione utente.
Oggi i principali browser mostrano comportamenti molto divergenti riguardo al modo in cui l'attivazione degli utenti
controlla le API basate su attivazione. In Chrome, l'implementazione si basava
basato su token che si è rivelato troppo complesso per definire
il comportamento di tutte le API basate sull'attivazione. Ad esempio, Chrome è stato
consentendo l'accesso incompleto alle API con attivazione
postMessage()
e
setTimeout()
chiamate; e l'attivazione dell'utente non è stata
supportato con Promises,
XHR,
Interazione con il gamepad e così via. Tieni presente che alcuni dei
sono infetti da tempo e molto diffusi.
Nella versione 72, Chrome offre Attivazione utente v2, che rende disponibilità dell'attivazione completata per tutte le API con attivazione. Questa operazione risolve le incoerenze indicate sopra (e altre, come MessageChannels), che riteniamo faciliterebbe il web sull'attivazione dell'utente. Inoltre, la nuova implementazione fornisce un'implementazione di riferimento per una proposta nuova specifica che mira a riunire tutti i browser nel lungo periodo.
Come funziona Attivazione utente v2?
La nuova API mantiene uno stato di attivazione utente a due bit per ogni oggetto window
nella gerarchia dei frame: un bit fisso per lo stato storico di attivazione dell'utente (se un
il frame ha mai visto l'attivazione di un utente) e un bit temporaneo per lo stato attuale.
(se un frame ha rilevato l'attivazione di un utente entro circa un secondo). La punta adesiva
non viene mai reimpostato durante il ciclo di vita del frame dopo che è stato impostato. Il bit transitorio
viene impostato a ogni interazione dell'utente e viene reimpostato dopo una scadenza
di servizio (circa un secondo) o tramite una chiamata a un'API che richiede l'attivazione
(ad es. window.open()
).
Tieni presente che le diverse API basate sull'attivazione si basano sull'attivazione dell'utente in
modi; la nuova API non modificherà nessuno di questi comportamenti specifici dell'API. Ad es.
è consentito un solo popup per attivazione utente perché window.open()
utilizza
come era in passato, Navigator.prototype.vibrate()
continua
essere efficace se un frame (o uno dei suoi frame secondari) ha subito azioni da parte degli utenti,
e così via.
Cosa cambierà?
- User Activation v2 formalizza la nozione di visibilità dell'attivazione dell'utente oltre i confini del frame: ora l'interazione dell'utente con un determinato frame attivare tutti i frame contenenti (e solo quelli) indipendentemente dai loro origine dati. In Chrome 72 abbiamo una soluzione alternativa temporanea per espandere visibilità a tutti i frame della stessa origine. Rimuoveremo questa soluzione alternativa una volta un modo per trasferire esplicitamente l'attivazione dell'utente ai frame secondari.)
- Quando un'API basata sull'attivazione viene chiamata da un frame attivato, ma all'esterno del codice di un gestore di eventi, funzionerà finché l'attivazione dell'utente lo stato è "attivo" (ad es. non è scaduto né è stato consumato). Prima dell'utente Attivazione v2, l'azione verrebbe annullata incondizionatamente.
- Più interazioni di utenti inutilizzati nell'intervallo di tempo di scadenza in un'unica attivazione corrispondente all'ultima interazione.
Esempi di coerenza nelle API basate sull'attivazione
Ecco due esempi di finestre popup (aperte utilizzando window.open()
) che
mostra come l'attivazione utente v2 genera il comportamento delle API basate sull'attivazione
coerente.
Chiamate setTimeout()
concatenate
Questo esempio proviene da
la nostra demo su setTimeout()
.
Se un gestore click
tenta di aprire un popup entro un secondo, dovrebbe
operazione riuscita indipendentemente da come il codice "compone" il ritardo. Attivazione utente v2 soddisfa
questa aspettativa, quindi ciascuno dei seguenti gestori di eventi apre un popup
click
(con un ritardo di 100 ms):
function popupAfter100ms() {
setTimeout(callWindowOpen, 100);
}
function asyncPopupAfter100ms() {
setTimeout(popupAfter100ms, 0);
}
someButton.addEventListener('click', popupAfter100ms);
someButton.addEventListener('click', asyncPopupAfter100ms);
Senza Attivazione utente v2, il secondo gestore di eventi ha esito negativo in tutti i browser viene testato. (Anche la prima non funziona in alcuni casi.
Chiamate postMessage()
interdominio
Ecco un esempio
la nostra demo su postMessage()
.
Supponiamo che un gestore click
in un sottoframe multiorigine invii due messaggi direttamente
al frame principale. Il frame principale dovrebbe essere in grado di aprire un popup su
quando si ricevono uno di questi messaggi (ma non entrambi):
// Parent frame code
window.addEventListener('message', e => {
if (e.data === 'open_popup' && e.origin === child_origin)
window.open('about:blank');
});
// Child frame code:
someButton.addEventListener('click', () => {
parent.postMessage('hi_there', parent_origin);
parent.postMessage('open_popup', parent_origin);
});
Senza Attivazione utente v2, il frame principale non può aprire un popup alla ricezione il secondo messaggio. Anche il primo messaggio non funziona se è "collegato" a un altro frame multiorigine (in altre parole, se il primo destinatario inoltra il messaggio a un altro).
Questa impostazione funziona con Attivazione utente v2, sia nel formato originale che con concatenamento.