JavaScript y las Cookies

JavaScript y las Cookies

Este artículo explica JavaScript y las cookies.

Explicaremos cuidadosamente todo paso a paso: desde los conceptos básicos de las cookies, la lectura y escritura, la seguridad, hasta ejemplos prácticos.

YouTube Video

javascript-cookie.html
  1<!DOCTYPE html>
  2<html lang="en">
  3<head>
  4  <meta charset="UTF-8">
  5  <title>JavaScript &amp; HTML</title>
  6  <style>
  7    * {
  8        box-sizing: border-box;
  9    }
 10
 11    body {
 12        margin: 0;
 13        padding: 1em;
 14        padding-bottom: 10em;
 15        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 16        background-color: #f7f9fc;
 17        color: #333;
 18        line-height: 1.6;
 19    }
 20
 21    .container {
 22        max-width: 800px;
 23        margin: 0 auto;
 24        padding: 1em;
 25        background-color: #ffffff;
 26        border: 1px solid #ccc;
 27        border-radius: 10px;
 28        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
 29    }
 30
 31    .container-flex {
 32        display: flex;
 33        flex-wrap: wrap;
 34        gap: 2em;
 35        max-width: 1000px;
 36        margin: 0 auto;
 37        padding: 1em;
 38        background-color: #ffffff;
 39        border: 1px solid #ccc;
 40        border-radius: 10px;
 41        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
 42    }
 43
 44    .left-column, .right-column {
 45        flex: 1 1 200px;
 46        min-width: 200px;
 47    }
 48
 49    h1, h2 {
 50        font-size: 1.2rem;
 51        color: #007bff;
 52        margin-top: 0.5em;
 53        margin-bottom: 0.5em;
 54        border-left: 5px solid #007bff;
 55        padding-left: 0.6em;
 56        background-color: #e9f2ff;
 57    }
 58
 59    button {
 60        display: block;
 61        margin: 1em auto;
 62        padding: 0.75em 1.5em;
 63        font-size: 1rem;
 64        background-color: #007bff;
 65        color: white;
 66        border: none;
 67        border-radius: 6px;
 68        cursor: pointer;
 69        transition: background-color 0.3s ease;
 70    }
 71
 72    button:hover {
 73        background-color: #0056b3;
 74    }
 75
 76    #output {
 77        margin-top: 1em;
 78        background-color: #1e1e1e;
 79        color: #0f0;
 80        padding: 1em;
 81        border-radius: 8px;
 82        min-height: 200px;
 83        font-family: Consolas, monospace;
 84        font-size: 0.95rem;
 85        overflow-y: auto;
 86        white-space: pre-wrap;
 87    }
 88
 89    .highlight {
 90        outline: 3px solid #ffc107; /* yellow border */
 91        background-color: #fff8e1;  /* soft yellow background */
 92        transition: background-color 0.3s ease, outline 0.3s ease;
 93    }
 94
 95    .active {
 96        background-color: #28a745; /* green background */
 97        color: #fff;
 98        box-shadow: 0 0 10px rgba(40, 167, 69, 0.5);
 99        transition: background-color 0.3s ease, box-shadow 0.3s ease;
100    }
101  </style>
102</head>
103<body>
104    <div class="container">
105        <h1>JavaScript Console</h1>
106        <button id="executeBtn">Execute</button>
107        <div id="output"></div>
108    </div>
109
110    <script>
111        // Override console.log to display messages in the #output element
112        (function () {
113            // Override console.log
114            const originalLog = console.log;
115            console.log = function (...args) {
116                originalLog.apply(console, args);
117                const message = document.createElement('div');
118                message.textContent = args.map(String).join(' ');
119                output.appendChild(message);
120            };
121
122            // Override console.error
123            const originalError = console.error;
124            console.error = function (...args) {
125                originalError.apply(console, args);
126                const message = document.createElement('div');
127                message.textContent = args.map(String).join(' ');
128                message.style.color = 'red'; // Color error messages red
129                output.appendChild(message);
130            };
131        })();
132
133        document.getElementById('executeBtn').addEventListener('click', () => {
134            // Prevent multiple loads
135            if (document.getElementById('externalScript')) return;
136
137            const script = document.createElement('script');
138            script.src = 'javascript-cookie.js';
139            script.id = 'externalScript';
140            //script.onload = () => console.log('javascript-cookie.js loaded and executed.');
141            //script.onerror = () => console.log('Failed to load javascript-cookie.js.');
142            document.body.appendChild(script);
143        });
144    </script>
145</body>
146</html>

JavaScript y las Cookies

Cookie se refiere a pequeños fragmentos de datos almacenados en el navegador del usuario. Se utilizan principalmente para los siguientes propósitos:.

  • Autenticación de usuario (mantener el estado de inicio de sesión)
  • Guardar la configuración del usuario (idioma, tema, etc.)
  • Seguimiento (historial de navegación, etc.)

En JavaScript, puedes leer y escribir cookies usando document.cookie.

Crear (escribir) cookies

Las cookies se crean con la siguiente sintaxis:.

1document.cookie = "username=JohnDoe";
  • Este código guarda una cookie llamada "username=JohnDoe" en el navegador.

Crear cookies con una fecha de expiración

Las cookies pueden tener una fecha de caducidad establecida. Si no se establece una fecha de caducidad, se trata como una cookie de sesión y se elimina cuando se cierra el navegador.

1const date = new Date();
2date.setTime(date.getTime() + (7 * 24 * 60 * 60 * 1000)); // 7 days
3const cookieText = "username=JohnDoe; expires=" + date.toUTCString() + "; path=/; SameSite=None; Secure"
4document.cookie = cookieText;
5console.log(`Cookie Text  : ${cookieText}`);
6console.log(`Cookie Value : ${document.cookie}`);
  • El atributo expires especifica la fecha de expiración de la cookie en formato UTC.
  • El atributo path especifica la ruta donde la cookie será enviada. / significa todo el sitio.
  • Si especificas SameSite=None, la Cookie se enviará incluso en solicitudes entre sitios. Sin embargo, en este caso, siempre debes incluir el atributo Secure.
  • Especificar Secure restringe la Cookie solo a comunicaciones HTTPS, lo que mejora la seguridad.
  • Al referenciar document.cookie, puedes obtener todas las Cookies disponibles en la página actual como una cadena.
  • Al usar console.log, puedes verificar la diferencia entre los valores reales de las Cookies establecidos en el navegador y los valores que se pueden recuperar.

Obtener (leer) cookies

Puedes obtener todas las cookies como una cadena de texto usando document.cookie.

1const date = new Date();
2date.setTime(date.getTime() + (7 * 24 * 60 * 60 * 1000)); // 7 days
3document.cookie = "theme=dark; expires=" + date.toUTCString() + "; path=/; SameSite=None; Secure"
4
5console.log(document.cookie);
6// Output: "username=JohnDoe; theme=dark"
  • El valor de retorno de document.cookie es una sola cadena en la que todas las Cookies están concatenadas en el formato 'clave=valor;'.
  • Es conveniente usar una función para analizar esta cadena y extraer el valor deseado.

Función para obtener el valor de una cookie

 1function getCookie(name) {
 2    const cookies = document.cookie.split('; ');
 3    for (const cookie of cookies) {
 4        const [key, value] = cookie.split('=');
 5        if (key === name) {
 6            return decodeURIComponent(value);
 7        }
 8    }
 9    return null;
10}
11
12console.log(getCookie("username")); // "JohnDoe"
  • Esta función divide las claves y los valores usando split() y devuelve el valor si coincide con la clave especificada.
  • Al utilizar decodeURIComponent, puedes recuperar correctamente los caracteres codificados.
  • Si la clave correspondiente no existe, devuelve null.

Eliminar cookies

Una cookie puede ser eliminada estableciendo su fecha de expiración en una fecha pasada.

1document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; SameSite=None; Secure";
2
3console.log(document.cookie);
4// Output: "theme=dark"
  • Al asignar un valor vacío a username y establecer la fecha de expiración en el pasado, será eliminada.
  • Al eliminar una Cookie, también debes hacer coincidir los atributos path, SameSite y Secure con los utilizados cuando se creó.
  • En este ejemplo, username se elimina y otras Cookies como theme=dark permanecen.

Opciones de cookies

Puedes especificar varias opciones para controlar el comportamiento de una cookie. Las principales son las siguientes:.

Especifica la fecha de expiración de la cookie en formato UTC. Si no se especifica, la cookie se convierte en una cookie de sesión y se elimina al cerrar el navegador.

Especifica la fecha de expiración de la cookie en segundos. Esto tiene prioridad sobre `expires`.

Especifica la ruta para la que la cookie será enviada. Por ejemplo, si especificas `/admin`, la cookie solo se enviará a las páginas bajo esa ruta.

Especifica el dominio para el cual la cookie es válida. Normalmente, se establece para el dominio actual, pero puedes aplicarlo a todos los subdominios, como `.example.com`.

Cuando se especifica este atributo, la cookie solo se envía a través de HTTPS. Para mejorar la seguridad, siempre configura este atributo para información sensible.

Controla si las cookies se envían en solicitudes entre sitios. Puedes especificar uno de los siguientes tres valores:.

- `Strict`
    Las cookies solo se envían para solicitudes del mismo sitio.

- `Lax`
    Las cookies se envían durante la navegación habitual, pero con algunas limitaciones.

- `None`
    Las cookies se pueden enviar incluso para solicitudes entre sitios. Sin embargo, también se requiere el atributo `Secure`.

Ejemplo: Cookie segura

1document.cookie = "sessionId=abc123; secure; SameSite=Strict";
  • Si especificas secure, la Cookie solo se enviará a través de comunicación HTTPS.
  • Si especificas SameSite=Strict, la Cookie no se enviará en solicitudes entre sitios, lo que la hace efectiva como medida contra CSRF.
  • Tales atributos de seguridad son esenciales para las Cookies importantes utilizadas para autenticación o gestión de sesiones.

Codificación y decodificación

Ya que los valores de las cookies pueden contener caracteres especiales, es más seguro usar encodeURIComponent.

1const date = new Date();
2date.setTime(date.getTime() + (7 * 24 * 60 * 60 * 1000)); // 7 days
3
4const username = "JohnDoe";
5document.cookie =
6    "username=" + encodeURIComponent(username) +
7    "; max-age=604800; path=/; SameSite=None; Secure";
8
9console.log(decodeURIComponent(getCookie("username"))); // "JohnDoe"
  • Al usar encodeURIComponent, puedes almacenar de forma segura espacios, símbolos, etc. en una Cookie.
  • Al leerla, usa decodeURIComponent para devolver la cadena original.
  • En este ejemplo, se usa max-age=604800 para establecer el periodo de expiración en 7 días (604,800 segundos). Este es un método para especificar la fecha de expiración, similar a expires. max-age puede especificarse en segundos y a menudo es más fácil de utilizar.

Ejemplo práctico: Guardar y cargar un tema

A continuación se muestra un ejemplo de cómo guardar el tema seleccionado por el usuario en una cookie y aplicarlo automáticamente en la siguiente visita.

 1function setTheme(theme) {
 2    document.cookie =
 3        "theme=" + encodeURIComponent(theme) +
 4        "; max-age=604800; path=/; SameSite=None; Secure"; // 1 week
 5    applyTheme(theme);
 6}
 7
 8function applyTheme(theme) {
 9    document.body.style.backgroundColor = theme === "dark" ? "#333" : "#fff";
10    document.body.style.color = theme === "dark" ? "#fff" : "#000";
11}
12
13function getCookie(name) {
14    const cookies = document.cookie.split('; ');
15    for (const cookie of cookies) {
16        const [key, value] = cookie.split('=');
17        if (key === name) {
18            return decodeURIComponent(value);
19        }
20    }
21    return null;
22}
23
24const savedTheme = getCookie("theme");
25if (savedTheme) {
26    applyTheme(savedTheme);
27}
1<button onclick="setTheme('light')">Light</button>
2<button onclick="setTheme('dark')">Dark</button>
  • La función setTheme guarda el tema seleccionado en una Cookie y llama de inmediato a applyTheme para actualizar la pantalla.
  • La función applyTheme cambia los colores de fondo y de texto del body según el tema.
  • En este ejemplo, dado que se establece max-age=604800, la configuración del tema se mantiene durante una semana.
  • Como la selección del usuario puede conservarse al volver a visitar la página, la experiencia de usuario (UX) mejora.

Limitaciones y precauciones de las cookies

Ten en cuenta los siguientes puntos al usar cookies:.

  • Limitaciones de tamaño El tamaño de una sola cookie está limitado a aproximadamente 4KB.

  • Límite en la cantidad de cookies que se pueden guardar Dependiendo del navegador, solo puedes guardar alrededor de 20 a 50 por dominio.

  • Precauciones de seguridad El contenido de las Cookies se guarda básicamente en texto plano, por lo que no es adecuado para almacenar información confidencial como contraseñas.

  • Cookies inaccesibles desde JavaScript Las Cookies con el atributo HttpOnly no pueden ser leídas por JavaScript por razones de seguridad.

Servidor y Cookies

1Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict

Algunos atributos de las Cookies, como HttpOnly, no se pueden establecer mediante JavaScript. Estos deben establecerse en el lado del servidor.

Resumen

Manipular las Cookies con JavaScript puede mejorar la experiencia del usuario y mantener el estado. Sin embargo, ten en cuenta los siguientes puntos para gestionarlas de forma segura y adecuada.

  • Guarda solo la información mínima necesaria Desde una perspectiva de privacidad y seguridad, evita almacenar información personal o sensible y guarda solo los datos necesarios.

  • Configura correctamente los atributos de seguridad Establece atributos como Secure y SameSite para evitar ataques de tipo cross-site como XSS y CSRF.

  • Codificación y decodificación de datos Utiliza encodeURIComponent y decodeURIComponent para guardar y leer de manera segura los valores de las Cookies, para que los caracteres especiales y el japonés se gestionen correctamente.

Al aprender la forma correcta de usar las Cookies, puedes construir aplicaciones web más avanzadas y seguras.

Puedes seguir el artículo anterior utilizando Visual Studio Code en nuestro canal de YouTube. Por favor, también revisa nuestro canal de YouTube.

YouTube Video