Che cos'è l'API Cookie Store?
L'API Cookie Store espone i cookie HTTP ai service worker e offre un'alternativa asincrona a document.cookie
. L'API semplifica le operazioni:
- Evita di danneggiare il thread principale accedendo ai cookie in modo asincrono.
- Evita di eseguire il polling per i cookie, perché è possibile che si verifichino modifiche ai cookie.
- Accedi ai cookie dei Service worker.
Leggi il messaggio esplicativo
Stato attuale
Passaggio | Stato |
---|---|
1. Crea messaggio esplicativo | Completato |
2. Crea bozza iniziale della specifica | Completato |
**3. Raccogli feedback e ottimizza le specifiche** | **In corso** |
4. Prova dell'origine | In pausa |
5. Avvia | Not started |
Come faccio a utilizzare l'archivio dei cookie asincroni?
Abilita la prova dell'origine
Per provarla localmente, l'API può essere abilitata dalla riga di comando:
chrome --enable-blink-features=CookieStore
La trasmissione di questo flag nella riga di comando abilita l'API a livello globale in Chrome per la sessione corrente.
In alternativa, puoi attivare il flag #enable-experimental-web-platform-features
in chrome://flags
.
Probabilmente i cookie non sono necessari
Prima di entrare nel vivo della nuova API, vorrei affermare che i cookie sono ancora la peggiore primitiva di archiviazione lato client della piattaforma web e devono comunque essere utilizzati come ultima risorsa. Non è un incidente: i cookie sono stati il primo meccanismo di archiviazione lato client del web e da allora abbiamo imparato molto.
Di seguito sono riportati i motivi principali per evitare i cookie:
I cookie portano lo schema di archiviazione nell'API di backend. Ogni richiesta HTTP trasporta uno snapshot dell'archivio cookie. In questo modo, per gli ingegneri di backend è più semplice introdurre dipendenze nel formato dei cookie attuale. Una volta eseguita questa operazione, il front-end non può modificare il proprio schema di archiviazione senza eseguire il deployment di una modifica corrispondente al backend.
I cookie hanno un modello di sicurezza complesso. Le moderne funzionalità della piattaforma web seguono gli stessi criteri di origine, ovvero ogni applicazione ha la propria sandbox ed è completamente indipendente da altre applicazioni che l'utente potrebbe eseguire. Gli ambiti dei cookie rendono la storia di sicurezza molto più complessa e il solo tentativo di riassumere, raddoppia le dimensioni di questo articolo.
I cookie hanno costi ad alte prestazioni. I browser devono includere uno snapshot dei cookie in ogni richiesta HTTP, pertanto ogni modifica ai cookie deve essere propagata negli stack di archiviazione e di rete. I browser moderni utilizzano implementazioni di archivi di cookie altamente ottimizzate, ma non saremo mai in grado di rendere i cookie efficienti come gli altri meccanismi di archiviazione, che non hanno bisogno di comunicare con lo stack di rete.
Per tutti i motivi di cui sopra, le applicazioni web moderne dovrebbero evitare i cookie e archiviare invece un identificatore di sessione in IndexedDB e aggiungerlo esplicitamente all'intestazione o al corpo di richieste HTTP specifiche, tramite l'API fetch.
Detto questo, stai ancora leggendo questo articolo perché hai un buon motivo per usare i cookie...
Lettura di un cookie ed eliminazione dei file jank
La venerabile API document.cookie è una fonte abbastanza garantita di jank per la tua applicazione. Ad esempio, ogni volta che utilizzi il getter document.cookie
, il browser deve interrompere l'esecuzione di JavaScript finché non riceve le informazioni sui cookie richieste. Questa operazione può richiedere un hop di processo o una lettura del disco e causa il jank della tua UI.
Una soluzione semplice per questo problema consiste nel passare dal getter document.cookie
all'API asincrona di Cookie Store.
await cookieStore.get('session_id');
// {
// domain: "example.com",
// expires: 1593745721000,
// name: "session_id",
// path: "/",
// sameSite: "unrestricted",
// secure: true,
// value: "yxlgco2xtqb.ly25tv3tkb8"
// }
Il setter document.cookie
può essere sostituito in modo simile. Tieni presente che l'applicazione della modifica è garantita solo dopo la risoluzione della promessa restituita da cookieStore.set
.
await cookieStore.set({name: 'opt_out', value: '1'});
// undefined
Osserva, non sondaggi
Un'applicazione molto diffusa per l'accesso ai cookie da JavaScript rileva quando
l'utente si disconnette e aggiorna l'interfaccia utente. Al momento, questo viene eseguito mediante il polling document.cookie
, che introduce jank e ha un impatto negativo sulla durata della batteria.
L'API Cookie Store offre un metodo alternativo per osservare le modifiche ai cookie, che non richiede il polling.
cookieStore.addEventListener('change', event => {
for (const cookie of event.changed) {
if (cookie.name === 'session_id') sessionCookieChanged(cookie.value);
}
for (const cookie of event.deleted) {
if (cookie.name === 'session_id') sessionCookieChanged(null);
}
});
Accogli i service worker
A causa della progettazione sincrona, l'API document.cookie
non è stata resa
disponibile per i
lavoratori dei servizi.
L'API Cookie Store è asincrona e, di conseguenza, è consentita nei service worker.
L'interazione con i cookie funziona allo stesso modo nei contesti dei documenti e nei service worker.
// Works in documents and service workers.
async function logOut() {
await cookieStore.delete('session_id');
}
Tuttavia, l'osservazione delle modifiche ai cookie è leggermente diversa nei service worker. Riattivare un service worker può essere piuttosto costoso, quindi dobbiamo descrivere esplicitamente le modifiche ai cookie a cui il worker è interessato.
Nell'esempio seguente, un'applicazione che utilizza IndexedDB per memorizzare nella cache i dati utente monitora le modifiche al cookie di sessione e ignora i dati memorizzati nella cache quando l'utente si disconnette.
// Specify the cookie changes we're interested in during the install event.
self.addEventListener('install', event => {
event.waitUntil(cookieStore.subscribeToChanges([{name: 'session_id'}]));
});
// Delete cached data when the user logs out.
self.addEventListener('cookiechange', event => {
for (const cookie of event.deleted) {
if (cookie.name === 'session_id') {
indexedDB.deleteDatabase('user_cache');
break;
}
}
});
best practice
Disponibile a breve.
Feedback
Se provi questa API, facci sapere cosa ne pensi. Invia il feedback sulla forma dell'API al repository delle specifiche e segnala i bug di implementazione al componente Blink Blink>Storage>CookiesAPI
.
Siamo particolarmente interessati a conoscere le misurazioni delle prestazioni e i casi d'uso oltre a quelli descritti nell'explainer.
Risorse aggiuntive
- Messaggio esplicativo pubblico
- Specifiche
- Bug di monitoraggio
- Voce chromestatus.com
- Thread del discorso su WCIG
- Componente lampeggiamento:
Blink>Storage>CookiesAPI