¿Qué es la API de Cookie Store?
La API de Cookie Store expone cookies HTTP a los trabajadores del servicio y ofrece una alternativa asíncrona a document.cookie
. La API facilita lo siguiente:
- Evita los bloqueos en el subproceso principal accediendo a las cookies de forma asíncrona.
- Evita sondear cookies, ya que se pueden observar cambios en ellas.
- Accede a las cookies desde los service workers.
Estado actual
Paso | Estado |
---|---|
1. Crea una explicación | Completar |
2. Crea un borrador inicial de la especificación | Completar |
**3. Recopilar comentarios y iterar en las especificaciones** | **En curso** |
4. Prueba de origen | Pausada |
5. Lanzamiento | Sin iniciar |
¿Cómo uso el almacén de cookies asíncrono?
Habilita la prueba de origen
Para probarla de forma local, la API se puede habilitar en la línea de comandos:
chrome --enable-blink-features=CookieStore
Si pasas esta marca en la línea de comandos, se habilita la API de forma global en Chrome para la sesión actual.
Como alternativa, puedes habilitar la marca #enable-experimental-web-platform-features
en chrome://flags
.
(Probablemente) no necesitas cookies
Antes de analizar la nueva API, me gustaría afirmar que las cookies siguen siendo la peor primitiva de almacenamiento del cliente de la plataforma web y deben usarse como último recurso. Esto no es un accidente: las cookies fueron el primer mecanismo de almacenamiento del cliente de la Web, y hemos aprendido mucho desde entonces.
Estos son los principales motivos para evitar las cookies:
Las cookies llevan tu esquema de almacenamiento a tu API de backend. Cada solicitud HTTP lleva un resumen del contenedor de cookies. Esto facilita que los ingenieros de backend introduzcan dependencias en el formato de cookie actual. Una vez que esto suceda, tu frontend no podrá cambiar su esquema de almacenamiento sin implementar un cambio coincidente en el backend.
Las cookies tienen un modelo de seguridad complejo. Las funciones de la plataforma web moderna siguen la misma política de origen, lo que significa que cada aplicación tiene su propia zona de pruebas y es completamente independiente de otras aplicaciones que el usuario pueda estar ejecutando. Los alcances de las cookies hacen que la historia de seguridad sea mucho más compleja, y solo intentar resumirla duplicaría el tamaño de este artículo.
Las cookies tienen costos de rendimiento altos. Los navegadores deben incluir un resumen de tus cookies en cada solicitud HTTP, por lo que cada cambio en las cookies debe propagarse en las pilas de almacenamiento y red. Los navegadores modernos tienen implementaciones de almacenamiento de cookies muy optimizadas, pero nunca podremos hacer que las cookies sean tan eficientes como los otros mecanismos de almacenamiento, que no necesitan comunicarse con la pila de red.
Por todos los motivos anteriores, las aplicaciones web modernas deben evitar las cookies y, en su lugar, almacenar un identificador de sesión en IndexedDB y agregar el identificador de forma explícita al encabezado o al cuerpo de solicitudes HTTP específicas a través de la API de fetch.
Dicho esto, sigues leyendo este artículo porque tienes un buen motivo para usar las cookies…
Cómo leer una cookie y eliminar la latencia
La API de document.cookie es una fuente bastante garantizada de bloqueos para tu aplicación. Por ejemplo, cada vez que usas el método get document.cookie
, el navegador debe dejar de ejecutar JavaScript hasta que tenga la información de la cookie que solicitaste. Esto puede requerir un salto de proceso o una lectura de disco, y hará que tu IU se bloquee.
Una solución directa para este problema es cambiar del método get de document.cookie
a la API asíncrona de Cookie Store.
await cookieStore.get('session_id');
// {
// domain: "example.com",
// expires: 1593745721000,
// name: "session_id",
// path: "/",
// sameSite: "unrestricted",
// secure: true,
// value: "yxlgco2xtqb.ly25tv3tkb8"
// }
El set document.cookie
se puede reemplazar de manera similar. Ten en cuenta
que solo se garantiza que el cambio se aplique después de que se resuelva la promesa que muestra
cookieStore.set
.
await cookieStore.set({name: 'opt_out', value: '1'});
// undefined
Observa, no sondees
Una aplicación popular para acceder a las cookies desde JavaScript es detectar cuándo el usuario sale y actualizar la IU. Actualmente, esto se realiza mediante el sondeo de document.cookie
, que introduce bloqueos y tiene un impacto negativo en la duración de batería.
La API de Cookie Store ofrece un método alternativo para observar los cambios en las cookies, que no requiere sondeos.
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);
}
});
Te damos la bienvenida a los service workers
Debido al diseño síncrono, la API de document.cookie
no se puso
a disposición de los
trabajadores en segundo plano.
La API de Cookie Store es asíncrona y, por lo tanto, se permite en los trabajadores de servicio.
La interacción con las cookies funciona de la misma manera en los contextos de documentos y en los trabajadores del servicio.
// Works in documents and service workers.
async function logOut() {
await cookieStore.delete('session_id');
}
Sin embargo, observar los cambios en las cookies es un poco diferente en los trabajadores del servicio. Activar un trabajador de servicio puede ser bastante costoso, por lo que debemos describir de forma explícita los cambios en las cookies que le interesan al trabajador.
En el siguiente ejemplo, una aplicación que usa IndexedDB para almacenar en caché los datos del usuario supervisa los cambios en la cookie de sesión y descarta los datos almacenados en caché cuando el usuario cierra la sesión.
// 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;
}
}
});
Prácticas recomendadas
Próximamente.
Comentarios
Si pruebas esta API, danos tu opinión. Envía comentarios sobre la forma de la API al repositorio de especificaciones y, luego, informa los errores de implementación al componente Blink Blink>Storage>CookiesAPI
.
Nos interesa especialmente conocer las mediciones de rendimiento y los casos de uso más allá de los que se describen en la explicación.
Recursos adicionales
- Explicación pública
- Especificación
- Error de seguimiento
- Entrada de chromestatus.com
- Hilo de Discourse de WICG
- Componente Blink:
Blink>Storage>CookiesAPI