Configura el comportamiento del almacenamiento en caché de HTTP

En este codelab, se muestra cómo cambiar los encabezados de almacenamiento en caché HTTP que devuelve un servidor web basado en Node.js, que ejecuta el framework de entrega Express. También se mostrará cómo confirmar que el comportamiento de almacenamiento en caché que esperas se aplique realmente, con el panel de redes en las Herramientas para desarrolladores de Chrome.

Familiarízate con el proyecto de ejemplo

Estos son los archivos clave con los que trabajarás en el proyecto de ejemplo:

  • server.js contiene el código de Node.js que entrega el contenido de la app web. Usa Express para controlar las solicitudes HTTP y las respuestas. En particular, express.static() se usa para entregar todos los archivos locales en el directorio público, por lo que la documentación de serve-static será útil.
  • public/index.html es el código HTML de la app web. Como la mayoría de los archivos HTML, no contiene información de control de versiones como parte de su URL.
  • public/app.15261a07.js y public/style.391484cf.css son los recursos de JavaScript y CSS de la app web. Cada uno de estos archivos contiene un hash en sus URLs, que corresponde a su contenido. El index.html es responsable de hacer un seguimiento de la URL con versión específica que se debe cargar.

Configura encabezados de almacenamiento en caché para nuestro HTML

Cuando respondas a solicitudes de URLs que no contengan información de control de versiones, asegúrate de agregar Cache-Control: no-cache a tus mensajes de respuesta. Además, se recomienda configurar uno de los dos encabezados de respuesta adicionales: Last-Modified o ETag. index.html pertenece a esta categoría. Puedes dividir este proceso en dos pasos.

Primero, los encabezados Last-Modified y ETag se controlan con las opciones de configuración etag y lastModified. Ambas opciones se establecen de forma predeterminada en true para todas las respuestas HTTP, por lo que, en esta configuración actual, no tienes que habilitar ese comportamiento. Sin embargo, puedes ser explícito en tu configuración de todos modos.

En segundo lugar, debes poder agregar el encabezado Cache-Control: no-cache, pero solo para tus documentos HTML (index.html, en este caso). La forma más sencilla de establecer este encabezado de manera condicional es escribir un setHeaders function personalizado y, dentro de él, verificar si la solicitud entrante es para un documento HTML.

La configuración de entrega estática en server.js comienza de la siguiente manera:

app.use(express.static('public'));
  • Realiza los cambios descritos anteriormente y deberías obtener un resultado similar al siguiente:
app.use(express.static('public', {
  etag: true, // Just being explicit about the default.
  lastModified: true,  // Just being explicit about the default.
  setHeaders: (res, path) => {
    if (path.endsWith('.html')) {
      // All of the project's HTML files end in .html
      res.setHeader('Cache-Control', 'no-cache');
    }
  },
}));

Configura encabezados de almacenamiento en caché para las URLs con versiones

Cuando respondas a solicitudes de URLs que contengan "huellas digitales" o información de versiones, y cuyo contenido nunca deba cambiar, agrega Cache-Control: max-age=31536000 a tus respuestas. app.15261a07.js y style.391484cf.css entran en esta categoría.

A partir de la función setHeaders function que se usó en el último paso, puedes agregar lógica adicional para verificar si una solicitud determinada es para una URL con versión y, de ser así, agregar el encabezado Cache-Control: max-age=31536000.

La forma más sólida de hacerlo es usar una expresión regular para ver si el recurso que se solicita coincide con un patrón específico en el que sabes que se encuentran los hashes. En el caso de este proyecto de ejemplo, siempre son ocho caracteres del conjunto de dígitos del 0 al 9 y las letras minúsculas de la a a la f (es decir, caracteres hexadecimales). El hash siempre está separado por un carácter . en ambos lados.

Una expresión regular que coincida con esas reglas generales se puede expresar como new RegExp('\\.[0-9a-f]{8}\\.').

  • Modifica la función setHeaders para que se vea de la siguiente manera:
app.use(express.static('public', {
  etag: true, // Just being explicit about the default.
  lastModified: true,  // Just being explicit about the default.
  setHeaders: (res, path) => {
    const hashRegExp = new RegExp('\\.[0-9a-f]{8}\\.');

    if (path.endsWith('.html')) {
      // All of the project's HTML files end in .html
      res.setHeader('Cache-Control', 'no-cache');
    } else if (hashRegExp.test(path)) {
      // If the RegExp matched, then we have a versioned URL.
      res.setHeader('Cache-Control', 'max-age=31536000');
    }
  },
}));

Confirma el comportamiento nuevo con las Herramientas para desarrolladores

Con las modificaciones en el servidor de archivos estáticos, puedes verificar que se establezcan los encabezados correctos obteniendo una vista previa de la app en vivo con el panel de red de Herramientas para desarrolladores abierto.

  • Para personalizar las columnas que se muestran en el panel de red y que incluyan la información más relevante, haz clic con el botón derecho en el encabezado de la columna:

Configura el panel de redes de las Herramientas para desarrolladores.

Aquí, las columnas a las que se debe prestar atención son Name, Status, Cache-Control, ETag y Last-Modified.

  • Con las Herramientas para desarrolladores abiertas en el panel de redes, actualiza la página.

Después de que se cargue la página, deberías ver entradas en el panel de red que se vean como las siguientes:

Columnas del panel de red.

La primera fila corresponde al documento HTML al que navegaste. Esto se entrega correctamente con Cache-Control: no-cache. El estado de respuesta HTTP para esa solicitud es un 304. Esto significa que el navegador sabía que no debía usar el HTML almacenado en caché de inmediato, sino que realizó una solicitud HTTP al servidor web, con la información de Last-Modified y ETag para ver si había alguna actualización del HTML que ya tenía en su caché. La respuesta HTTP 304 indica que no hay HTML actualizado.

Las siguientes dos filas son para los recursos de JavaScript y CSS con control de versiones. Deberías ver que se entregan con Cache-Control: max-age=31536000 y que el estado HTTP de cada uno es 200. Debido a la configuración que se usó, no se realiza ninguna solicitud real al servidor de Node.js, y, si haces clic en la entrada, se mostrarán detalles adicionales, incluido que la respuesta provino de la memoria caché del disco.

Un estado de respuesta de red de 200

Los valores reales de las columnas ETag y Last-Modified no importan mucho. Lo importante es confirmar que se estén configurando.

En resumen

Después de seguir los pasos de este codelab, ya sabes cómo configurar los encabezados de respuesta HTTP en un servidor web basado en Node.js con Express para un uso óptimo de la caché HTTP. También tienes los pasos que necesitas para confirmar que se está usando el comportamiento de almacenamiento en caché esperado, a través del panel de red en las Herramientas para desarrolladores de Chrome.