En un post anterior explicábamos qué son las cookies, como funcionan y hacíamos un repaso de todos sus parámetros y características. Si no leíste ese tutorial, te recomiendo hacerlo antes de seguir o puede que no entiendas algunas de las cosas que trataremos aquí, en especial la sintaxis y detalles de cada parámetro. Hoy nos vamos a centrar en el uso de cookies en JavaScript y le dedicaremos poco a ese apartado.

Repaso rápido

Una cookie es un string (cadena de texto) que contiene parejas parametro=valor separadas por ; de la siguiente forma:

<nombre>=<valor>; expires=<fecha>; max-age=<segundos>; path=<ruta>; domain=<dominio>; secure; httponly;

Los parámetros son:

<nombre>=<valor>
Requerido. <nombre> es el nombre (key) que identifica la cookie y <valor> es su valor. A diferencia de las cookies en PHP, en JavaScript se puede crear una cookie con un valor vacío (<nombre>=).
expires=<fecha> y max-age=<segundos>
Opcional. Ambos parámetros especifican el tiempo de validez de la cookie. expires establece una fecha (ha de estar en formato UTC) mientras que max-age establece una duración máxima en segundos. max-age toma preferencia sobre expires. Si no se especifica ninguno de los dos se creará una session cookie. Si es max-age=0 o expires=fecha-pasada la cookie se elimina.
path=<ruta>
Opcional. Establece la ruta para la cuál la cookie es válida. Si no se especifica ningún valor, la cookie será válida para la ruta la página actual.
domain=<dominio>
Opcional. Dentro del dominio actual, subdominio para el que la cookie es válida. El valor predeterminado es el subdominio actual. Establecer domain=.miweb.com para una cookie que sea válida para cualqueir subdominio (nota el punto delante del nombre del dominio). Por motivos de seguridad, los navegadores no permiten crear cookies para dominios diferentes al que crea la cookie (same-origin policy).
secure
Opcional. Parámetro sin valor. Si está presente la cookie sólo es válida para conexiones encriptadas (por ejemplo mediante protocolo HTTPS).
HttpOnly
Opcional. Parámetro no disponible en JavaScript ya que crea cookies válidas sólo para protocolo HTTP/HTTPS y no para otras APIs, incluyendo JavaScript.

La propiedad document.cookie

La propiedad document.cookie es todo lo que se necesita para trabajar con cookies client-side desde JavaScript. A través de ella podemos crear, leer, modificar y eliminar cookies. Veamos cada uno de los casos.

1

Crear cookies

Establecer una cookie en JavaScript es tan fácil como crear el string que define la cookie y asignarlo a document.cookie. Por ejemplo:

document.cookie = "nombrecookie=valorcookie; max-age=3600; path=/";

Si queremos crear varias cookies, tenemos que hacer este paso una vez para cada una. Por ejemplo, con el siguiente código se crearían las cookies comida_favorita y color_favorito:

document.cookie = "comida_favorita=arroz; max-age=3600; path=/";
document.cookie = "color_favorito=amarillo";

Este comportamiento se debe a que document.cookie no es un dato con un valor (data property), sino una propiedad de acceso con métodos set y get nativos (accessor property). Cada vez que se le asigna una nueva cookie, no se sobrescriben las cookies anteriores sino que la nueva se añade a la colección de cookies del documento.

Recuerda que las cookies se envían en las cabeceras HTTP y, por tanto, deben estar correctamente codificadas. Puedes utilizar encodeURIComponent(), acostúmbrate a utilizarlo siempre para evitarte sorpresas:

var testvalue = "Hola mundo!";
document.cookie = "testcookie=" + encodeURIComponent( testvalue );

Si vas a utilizar el parámetro expires, recuerda que ha de ser una fecha en formato UTC. Te puede ser de ayuda el método Date.toUTCString(). Por ejemplo, una cookie con caducidad para el 1 de Febrero del año 2068 a las 11:20:

var expiresdate = new Date(2068, 1, 02, 11, 20);
var cookievalue = "Hola Mundo!";
document.cookie = "testcookie=" + encodeURIComponent( cookievalue ) + "; expires=" + expiresdate.toUTCString();

Recuerda también que si no se específica fecha de caducidad la cookie será válida sólo para la sesión actual.

2

Modificar cookies

En el punto anterior se dijo que cada vez que se asigna una cookie a document.cookie, esta es añadida a la colección de cookies del documento. Esto es verdad excepto si la cookie asignada tiene un identificador que ya existe. En este caso se modifica la cookie existente en lugar de añadir una más.

Por ejemplo, podemos crear la siguiente cookie con identificador nombre y valor Miguel:

document.cookie = "nombre=Miguel";

Si queremos modificar el valor, por ejemplo cambiarlo por Juan:

document.cookie = "nombre=Juan";

Es importante tener en cuenta que si una cookie se crea para un dominio o para un path determinado y se quiere modificar, el dominio y el path han de coincidir. De lo contrario se crearán dos cookies diferentes válidas para cada path y dominio. Por ejemplo, imaginemos que estamos en “miweb.com/blog” (el valor predeterminado del path es en este caso /blog):

// Supongamos que estamos en "miweb.com/blog"
// y creamos las siguientes cookies

// Creamos la cookie para el path "/"
document.cookie = "nombre=Miguel; path=/";

// Con la siguiente linea se crea una nueva cookie para el path "/blog" (valor por defecto)
// pero no se modifica la cookie "nombre" anterior porque era para un path diferente
document.cookie = "nombre=Juan";

// Con la siguiente línea SI se modifica la cookie "nombre" del path "/" correctamente
document.cookie = "nombre=Juan; path=/";
3

Eliminar cookies

Para eliminar una cookie desde JavaScript se debe asignar una fecha de caducidad (expires) pasada o un max-age igual a cero. En ambos casos da igual el valor que se le asigne a la cookie porque se eliminará pero ha de darse el nombre de la cookie aunque sea sin valor.

Por ejemplo, creamos la cookie con el identificador nombre y valor Miguel igual que antes:

document.cookie = "nombre=Miguel";

Si queremos eliminarla:

document.cookie = "nombre=; expires=Thu, 01 Jan 1970 00:00:00 UTC";

// O con max-age
document.cookie = "nombre=; max-age=0";

Al igual que ocurría con la modificación de cookies, para la eliminación el path y el dominio también tienen que coincidir:

// Se crean dos cookies con el mismo identificador
// para dos paths diferentes
document.cookie = "nombre=Miguel; path=/noticias";
document.cookie = "nombre=Juan; path=/blog";

// Solo se elimina la cookie del path /noticias
document.cookie = "nombre=; max-age=0; path=/noticias";
4

Leer y obtener el valor de las cookies

Puede que obtener el valor sea el paso más tedioso de trabajar con cookies en JavaScript, y es que no hay un método de lectura directo para cada cookie individual. Sólo se puede obtener un string con todas las cookies válidas para el documento y manipular el string hasta encontrar el nombre y valor de la cookie que queremos.

El string con todas las cookies se obtiene del siguiente modo:

var lasCookies = document.cookie;

Y tiene el siguiente formato:

"cookie1=valor1;cookie2=valor2;cookie3=valor3[;...]"

Quiero remarcar los siguientes aspectos:

  1. El string sólo contiene pares de nombre de la cookie y su valor. No se puede acceder a otros parámetros a través de document.cookie.
  2. Sólo se obtienen las cookies válidas para el documento actual. Esto implica que cookies para otros paths, dominios o cookies caducadas no se pueden leer. Aunque en una página puedan crearse cookies para otros subdominios y paths, sólo se pueden leer las que san válidas para el subdominio y path actual.

Por ejemplo, imagina que estamos en la subdominio noticias.miweb.com. Aquí podemos crear una cookie para el subdominio tienda.miweb.com, pero esta cookie no es válida para el documento en el que estamos (noticias.miweb.com), por lo que no podemos leer su valor desde aquí, aunque sí hemos podido crearla:

// Suponiendo que estamos en noticias.miweb.com

// Se crean dos cookies para dos subdominios diferentes
document.cookie = "cookienoticias=valorcn; domain=noticias.miweb.com";
document.cookie = "cookietienda=valorct; domain=tienda.miweb.com";

var lasCookies = document.cookie;
alert( lasCookies );
// Obtendremos cookienoticias=valorcn
// No podemos acceder a la cookie cookietienda
// porque es válida solo para tienda.miweb.com y estamos en noticias.miweb.com

Ahora que sabemos cómo obtener las cookies, ¿cómo leemos los valores de cookies individuales? Pues tenemos que manipular el string con todas las cookies y dividirlo por cada ; para separar cada par nombrecookie=valor. Luego se divide cada uno de estos pares por = para separar el nombre de la cookie y su valor. Se puede conseguir utilizando varios métodos, a continuación algunos de los más comunes:

Ejemplo con split

// Adapatado de http://www.quirksmode.org/js/cookies.html#script
function readCookie(name) {

  var nameEQ = name + "="; 
  var ca = document.cookie.split(';');

  for(var i=0;i < ca.length;i++) {

    var c = ca[i];
    while (c.charAt(0)==' ') c = c.substring(1,c.length);
    if (c.indexOf(nameEQ) == 0) {
      return decodeURIComponent( c.substring(nameEQ.length,c.length) );
    }

  }

  return null;

}

// Creamos una cookie
document.cookie = "pais=" + encodeURIComponent( "Uruguay" );

// Leemos la cookie
var miCookie = readCookie( "pais" );

// Muestra "Uruguay"
alert( miCookie );

Ejemplo con regex

function readCookie(name) {

  return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + name.replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;

}

// Creamos una cookie
document.cookie = "pais=" + encodeURIComponent( "Ecuador" );

// Leemos la cookie
var miCookie = readCookie( "pais" );

// Muestra "Ecuador"
alert( miCookie );

Puedes elegir el que quieras o utilizar alguno de los cientos de snippets que circulan por la red que te harán la vida más fácil. Personalmente me gustan el framework que proponen en MDN y JS Cookie.

Referencias