Este codelab mostra como mudar os cabeçalhos de cache HTTP retornados por um servidor da Web baseado em Node.js, executando o framework de serviço Express. Ele também mostra como confirmar se o comportamento de armazenamento em cache esperado está sendo aplicado usando o painel "Rede" do DevTools do Chrome.
Conhecer o projeto de exemplo
Estes são os principais arquivos com que você vai trabalhar no projeto de exemplo:
server.js
contém o código Node.js que veicula o conteúdo do app da Web. Ele usa o Express para processar solicitações e respostas HTTP. Em particular,express.static()
é usado para veicular todos os arquivos locais no diretório público. Portanto, a documentação doserve-static
será útil.public/index.html
é o HTML do app da Web. Como a maioria dos arquivos HTML, ele não contém informações de controle de versões como parte do URL.public/app.15261a07.js
epublic/style.391484cf.css
são os recursos JavaScript e CSS do app da Web. Cada um desses arquivos contém um hash nos URLs, que corresponde ao conteúdo. Oindex.html
é responsável por manter o controle de qual URL com versão específica carregar.
Configurar cabeçalhos de cache para nosso HTML
Ao responder a solicitações de URLs que não contêm informações de controle de versão, adicione Cache-Control: no-cache
às mensagens de resposta. Além disso, é recomendável definir um dos dois cabeçalhos de resposta adicionais: Last-Modified
ou ETag
. O
index.html
se enquadra nessa categoria. Você pode dividir isso em duas etapas.
Primeiro, os cabeçalhos Last-Modified
e ETag
são controlados pelas opções de configuração
etag
e
lastModified
. As duas opções usam true
como padrão para todas as respostas HTTP. Portanto, na configuração atual, você não precisa ativar esse comportamento. Mas você pode ser explícito na sua configuração de qualquer maneira.
Em segundo lugar, você precisa adicionar o cabeçalho Cache-Control: no-cache
, mas
apenas para seus documentos HTML (index.html
, neste caso). A maneira mais fácil de
definir esse cabeçalho condicionalmente é escrever um
setHeaders function
personalizado
e, dentro dele, verificar se a solicitação recebida é para um documento HTML.
- Clique em Remixar para editar e tornar o projeto editável.
A configuração de veiculação estática em server.js
começa assim:
app.use(express.static('public'));
- Faça as mudanças descritas acima. O resultado vai ser algo parecido com isto:
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');
}
},
}));
Configurar cabeçalhos de cache para os URLs com versões
Ao responder a solicitações de URLs que contenham "fingerprint" ou informações de controle de versão e cujo conteúdo nunca deva mudar, adicione Cache-Control: max-age=31536000
às suas respostas. Os app.15261a07.js
e
style.391484cf.css
se enquadram nessa categoria.
Com base no
setHeaders function
usado na última etapa, você pode adicionar outra lógica para verificar se uma determinada
solicitação é para um URL com versão e, em caso afirmativo, adicionar o cabeçalho Cache-Control:
max-age=31536000
.
A maneira mais robusta de fazer isso é usar uma
expressão regular
para verificar se o recurso solicitado corresponde a um padrão específico que você
sabe que os hashes se enquadram. No caso deste projeto de exemplo, são sempre oito
caracteres do conjunto de dígitos 0 a 9 e letras minúsculas de a a f (ou seja,
caracteres hexadecimais). O hash
sempre é separado por um caractere .
em ambos os lados.
Uma expressão regular que corresponde a essas regras gerais pode ser expressa como new RegExp('\\.[0-9a-f]{8}\\.')
.
- Modifique a função
setHeaders
para que ela fique assim:
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');
}
},
}));
Confirmar o novo comportamento usando o DevTools
Com as modificações no servidor de arquivos estáticos, você pode verificar se os cabeçalhos corretos estão sendo definidos ao visualizar o app ativo com o painel de rede do DevTools aberto.
- Personalize as colunas mostradas no painel "Rede" para incluir as informações mais relevantes. Para isso, clique com o botão direito do mouse no cabeçalho da coluna:
Aqui, as colunas a serem observadas são Name
, Status
, Cache-Control
, ETag
e Last-Modified
.
- Com o DevTools aberto no painel "Rede", atualize a página.
Depois que a página for carregada, você verá entradas no painel "Rede" semelhantes a estas:
A primeira linha é para o documento HTML que você acessou. Isso é veiculado corretamente com Cache-Control: no-cache
. O status da resposta HTTP para essa solicitação
é 304
. Isso significa que o navegador sabia que não deveria usar o HTML em cache imediatamente, mas fez uma solicitação HTTP ao servidor da Web, usando as informações Last-Modified
e ETag
para verificar se havia alguma atualização no HTML que já estava no cache. A resposta HTTP 304 indica que não há HTML atualizado.
As duas linhas seguintes são para os recursos JavaScript e CSS com controle de versão. Eles devem ser veiculados com Cache-Control: max-age=31536000
, e o status HTTP de cada um é 200
.
Devido à configuração usada, nenhuma solicitação real é feita ao
servidor Node.js. Ao clicar na entrada, você verá mais detalhes,
incluindo que a resposta veio "(do cache de disco)".
Os valores reais das colunas "ETag" e "Last-Modified" não importam muito. O importante é confirmar que eles estão sendo definidos.
Resumindo
Depois de seguir as etapas deste codelab, você já sabe como configurar os cabeçalhos de resposta HTTP em um servidor da Web baseado em Node.js usando o Express, para uso ideal do cache HTTP. Você também tem as etapas necessárias para confirmar que o comportamento de cache esperado está sendo usado, pelo painel "Rede" nas DevTools do Chrome.