Por que essa resposta está sendo armazenada em cache?

32

Eu tenho um cliente cujo site index.html atualmente volta com estes cabeçalhos:

Accept-Ranges: bytes
Conexão: Keep-Alive
Codificação de conteúdo: gzip
Comprimento do conteúdo: 3658
Tipo de Conteúdo: text / html
Data: quinta-feira, 10 de outubro de 2013 07:36:27 GMT
ETag: "4aa95e1-2ed2-4e721324728b7"
Manter ativo: tempo limite = 5, máximo = 100
Última modificação: ter, 24 set 2013 13:34:30 GMT
Servidor: Apache / 2.2.22
Variar: Aceitar-codificação, User-Agent

Estou, obviamente, vai recomendar que eles adicionar Expiresou Cache-Controlconforme o caso, mas estou confuso: Chrome armazena em cache este recurso e usa-lo a partir do cache (não enviar um pedido a todos ), mesmo após várias horas (por exemplo, ele reutilizado uma cópia em cache ontem às 13h30 desta manhã às 8h30). Eu posso ver isso claramente na guia Rede do console do Chrome, onde mostra a solicitação e está 200 (OK)em cinza na coluna Status e (from cache)na coluna Tamanho . (Não alterei os padrões de cache do Chrome.)

Percebo que a especificação permite que os agentes usuários tomem suas próprias decisões na ausência de orientação dos cabeçalhos. É isso que está acontecendo aqui? O Chrome vê que foi modificado pela última vez há alguns dias e sente-se à vontade para usar uma versão que está (digamos) atualizada até um dia desatualizado? Ou há algo que estou perdendo?

TJ Crowder
fonte

Respostas:

33

Quando os cabeçalhos "Expira" e "Controle de cache" não são especificados, mas um cabeçalho "Última modificação" é especificado, os navegadores precisam adivinhar quanto tempo devem manter o documento no cache. Alguns navegadores fazem uso de algoritmos que permitem que a página de permanecer em cache para um dia ou mais.

O guia de práticas recomendadas de cache do Google declara:

Last-Modified é um cabeçalho de cache "fraco", em que o navegador aplica uma heurística para determinar se deve buscar o item no cache ou não. (As heurísticas são diferentes entre diferentes navegadores.)


O Mozilla (Firefox) possui uma FAQ sobre cache de HTTP que descreve seu algoritmo para esta situação (embora seja possível que o algoritmo tenha sido alterado desde que o documento é datado de 2002):

... procuramos um cabeçalho "Última modificação". Se esse cabeçalho estiver presente, o tempo de vida útil do cache será igual ao valor do cabeçalho "Data" menos o valor do cabeçalho "Última modificação" dividido por 10.

Portanto, no caso em que a diferença entre modificado e agora é de 15 dias, o Firefox armazenará o recurso em cache por 1,5 dias.

Parece que todos os principais navegadores usam a mesma regra de 10% que o Firefox implementa. Uma pergunta foi feita no StackOveflow solicitando essas heurísticas . Respostas diferentes para diferentes navegadores mostram que todos eles têm implementações semelhantes. Existem respostas para o Internet Explorer e Webkit (Chrome e Safari).


O tamanho do cache do navegador provavelmente será o fator limitante para um arquivo que o algoritmo de cache determina que pode ser mantido por mais de um dia. Os navegadores geralmente têm uma configuração para a quantidade de espaço em disco que eles usam para o cache. Muitos usuários também limpam o cache quando fecham o navegador. Portanto, a quantidade de tempo em que esse arquivo é armazenado em cache geralmente depende de:

  • A quantidade de espaço em cache que o navegador alocou
  • O número de sites que um usuário visita (e o tamanho desses sites)
  • Se o usuário fechou ou não o navegador
Stephen Ostermiller
fonte
Você pode esclarecer "o Firefox armazenaria o recurso em cache por 1,5 dias". A partir de qual data, ele armazenará em cache até 1,5 dias? Se já são 15 dias, já teria expirado, não é? E como o NOW menos a última modificação será sempre aumentada, você quer dizer, será armazenado em cache para sempre!
myDoggyWritesCode
1
Não para sempre. Por 1/10 do tempo entre o último cabeçalho modificado e o horário do download. Se já passaram 15 dias para você, isso pode significar 150 dias desde a última modificação do arquivo.
Stephen Ostermiller