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 muestra un servidor web basado en Node.js que ejecuta el framework de entrega de Express. También te mostrará cómo confirmar que se está aplicando el comportamiento de almacenamiento en caché que esperas con el panel de red de DevTools 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 y respuestas HTTP. 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 te resultará útil.
  • public/index.html es el código HTML de la app web. Al igual que 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. index.html es responsable de realizar un seguimiento de la URL con versión específica que se cargará.

Configura los encabezados de almacenamiento en caché para nuestro HTML

Cuando respondas solicitudes de URLs que no contienen información sobre el 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 dividirlo en dos pasos.

En primer lugar, los encabezados Last-Modified y ETag están controlados por las opciones de configuración etag y lastModified. En realidad, ambas opciones son true de forma predeterminada para todas las respuestas HTTP, por lo que, en esta configuración actual, no tienes que habilitar la opción para obtener ese comportamiento. De cualquier manera, puedes ser explícito en tu configuración.

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 fácil de configurar este encabezado de forma condicional es escribir un setHeaders function personalizado y, dentro de él, verificar si la solicitud entrante es para un documento HTML.

  • Haz clic en Remix para editar para que el proyecto sea editable.

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

app.use(express.static('public'));
  • Realiza los cambios descritos anteriormente y deberías obtener algo similar a lo 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 control de versiones

Cuando respondas solicitudes de URLs que contengan información de "huella digital" o de control de versiones, y cuyo contenido nunca debe 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 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í, agrega 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 activo que se solicita coincide con un patrón específico en el que sabes que se encuentran los valores hash. En el caso de este proyecto de muestra, 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 . a cada lado.

Una expresión regular que coincide 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 DevTools

Con las modificaciones realizadas en el servidor de archivos estáticos, puedes verificar que se establezcan los encabezados correctos. Para ello, obtén una vista previa de la app en vivo con el panel de red de DevTools abierto.

  • Para obtener una vista previa del sitio, presiona Ver app. Luego, presiona Pantalla completa pantalla completa.

  • Haz clic con el botón derecho en el encabezado de la columna para personalizar las columnas que se muestran en el panel Network a fin de incluir la información más relevante:

Configuración del panel Network de DevTools

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

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

Después de cargar la página, deberías ver entradas en el panel Network que lucen de la siguiente manera:

Columnas del panel de red

La primera fila corresponde al documento HTML al que navegaste. Se entrega correctamente con Cache-Control: no-cache. El estado de la respuesta HTTP para esa solicitud es 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 versión. Deberías ver que se entregan con Cache-Control: max-age=31536000 y el estado HTTP de cada uno es 200. Debido a la configuración utilizada, 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 proviene de “(from disk cache)”.

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 conoces cómo configurar los encabezados de respuesta HTTP en un servidor web basado en Node.js con Express, para usar de forma óptima la caché HTTP. También tienes los pasos que necesitas para confirmar que se usa el comportamiento de almacenamiento en caché esperado a través del panel de red en DevTools de Chrome.