Para responder à sua pergunta sobre por que o cache está funcionando, mesmo que o servidor da Web não tenha incluído os cabeçalhos:
- Expira em:
[a date]
- Controle de cache: idade máxima =
[seconds]
O servidor solicitou aos proxies intermediários que não armazenassem em cache o conteúdo (ou seja, o item só deve ser armazenado em cache em um cache privado , ou seja, apenas em sua própria máquina local):
- Controle de cache: privado
Mas o servidor esqueceu de incluir qualquer tipo de dicas de cache:
- eles esqueceram de incluir Expira , para que o navegador saiba usar a cópia em cache até essa data
- eles esqueceram de incluir a idade máxima , para que o navegador saiba por quanto tempo o item armazenado em cache é bom para
- eles esqueceram de incluir E-Tag , para que o navegador possa fazer uma solicitação condicional
Mas eles incluíram uma data da última modificação na resposta:
Last-Modified: Tue, 16 Oct 2012 03:13:38 GMT
Como o navegador sabe a data em que o arquivo foi modificado, ele pode executar uma solicitação condicional . Ele solicitará o servidor pelo arquivo, mas instruirá o servidor a enviar o arquivo somente se ele tiver sido modificado desde 16/10/2012 3:13:38:
GET / HTTP/1.1
If-Modified-Since: Tue, 16 Oct 2012 03:13:38 GMT
O servidor recebe a solicitação, percebe que o cliente já possui a versão mais recente. Em vez de enviar o cliente 200 OK
, seguido pelo conteúdo da página, ele informa que sua versão em cache é boa:
304 Not Modified
Seu navegador teve que sofrer o atraso de enviar uma solicitação ao servidor e aguardar uma resposta, mas economizou a necessidade de baixar novamente o conteúdo estático.
Por que Max-Age ? Por que expira ?
Porque Last-Modified é uma merda.
Nem tudo no servidor tem uma data associada. Se estou criando uma página rapidamente, não há data associada a ela - agora é . Mas estou perfeitamente disposto a deixar o usuário armazenar em cache a página inicial por 15 segundos:
200 OK
Cache-Control: max-age=15
Se o usuário martelar F5, ele continuará recebendo a versão em cache por 15 segundos. Se for um proxy corporativo, todos os 67198 usuários que acessarem a mesma página na mesma janela de 15 segundos obterão o mesmo conteúdo - todos servidos a partir do cache próximo. Vitória de desempenho para todos.
A virtude de adicionar Cache-Control: max-age
é que o navegador nem precisa executar uma solicitação condicional .
- se você especificou apenas
Last-Modified
, o navegador deve executar uma solicitação If-Modified-Since
e aguardar uma 304 Not Modified
resposta
- se você especificou
max-age
, o navegador não precisará sofrer a ida e volta da rede; o conteúdo sairá diretamente dos caches
A diferença entre "Controle de cache: idade máxima" e "Expira"
Expires
é um equivalente herdado do Cache-Control: max-age
cabeçalho moderno (c. 1998) :
Expires
: você especifica uma data (eca)
max-age
: você especifica segundos (Deus)
E se ambos forem especificados, o navegador usará max-age
:
200 OK
Cache-Control: max-age=60
Expires: 20180403T192837
Qualquer site escrito após 1998 não deve Expires
mais usar , e sim usar max-age
.
O que é ETag?
ETag é semelhante ao Last-Modified , exceto que ele não precisa ser uma data - apenas tem que ser algo .
Se eu estiver retirando uma lista de produtos de um banco de dados, o servidor poderá enviar o último rowversion
como um ETag, em vez de uma data:
200 OK
ETag: "247986"
Meu ETag pode ser o hash SHA1 de um recurso estático (por exemplo, imagem, js, css, fonte) ou da página renderizada em cache (ou seja, é isso que o wiki do Mozilla MDN faz; eles possuem a marcação final):
200 OK
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
E exatamente como no caso de uma solicitação condicional com base na última modificação :
GET / HTTP/1.1
If-Modified-Since: Tue, 16 Oct 2012 03:13:38 GMT
304 Not Modified
Eu posso executar uma solicitação condicional com base no ETag:
GET / HTTP/1.1
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
304 Not Modified
Um ETag
é superior a, Last-Modified
porque funciona para coisas além de arquivos ou coisas que têm uma noção de data . Ele só é