O que é o Cache-Control: private?

148

Quando visito chesseng.herokuapp.com , recebo um cabeçalho de resposta que se parece com

Cache-Control:private
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/css
Date:Tue, 16 Oct 2012 06:37:53 GMT
Last-Modified:Tue, 16 Oct 2012 03:13:38 GMT
Status:200 OK
transfer-encoding:chunked
Vary:Accept-Encoding
X-Rack-Cache:miss

e depois atualizo a página e recebo

Cache-Control:private
Connection:keep-alive
Date:Tue, 16 Oct 2012 06:20:49 GMT
Status:304 Not Modified
X-Rack-Cache:miss

então parece que o cache está funcionando. Se isso funciona para armazenamento em cache, qual é o objetivo de Expira e Controle de cache: idade máxima . Para aumentar a confusão, quando testo a página em https://developers.google.com/speed/pagespeed/insights/, ele diz para "Aproveitar o cache do navegador".

user782220
fonte
verifique este diagrama stackoverflow.com/a/49925190/3748498
pravdomil:

Respostas:

74

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-Sincee aguardar uma 304 Not Modifiedresposta
  • 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-agecabeç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 Expiresmais 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 rowversioncomo 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-Modifiedporque funciona para coisas além de arquivos ou coisas que têm uma noção de data . Ele só é

Ian Boyd
fonte
1
Impressionante! Eu coloquei uma recompensa por esta resposta. O que acontece se cache-controlnão existir? E você só tem Etag? Ainda não é necessário fazer uma 'solicitação condicional' contra o servidor? O comportamento que estou vendo quando estou offline é que ele retorna do cache. Mas quando está offline, não pode fazer essa solicitação condicional. Então, isso significa se ele será armazenado em cache indefinidamente se você permanecer offline? Eu já fiz essa pergunta em detalhes aqui . Você pode dar uma olhada?
Mel
167
Cache-Control: private

Indica que toda ou parte da mensagem de resposta se destina a um único usuário e NÃO DEVE ser armazenada em cache por um cache compartilhado, como um servidor proxy.

Da seção 14.9.1 da RFC2616

Dan D.
fonte
14
Porque foi armazenado em cache pelo seu navegador. Você é o usuário único para o qual a resposta foi planejada.
Dan D.
13
Não, não é Cache-Control:privateapenas porque os estados que caches compartilhados (como caches de proxy) não devem armazenar em cache a resposta.
Dan D.
5
@Trejkaz Não, realmente significa um único usuário. Um usuário é uma conta que possui seu próprio diretório inicial no qual o cache reside. Os perfis pertencentes ao mesmo usuário podem compartilhar seu cache. Como você encontrou. Mas dois perfis no mesmo computador, se pertencentes a usuários diferentes, não devem compartilhar seu cache, a menos que esse cache seja tratado como um cache compartilhado.
Dan D.
2
Ah, então é por usuário no nível do SO. Sim, a razão pela qual me pergunto é por causa de um aparente vazamento de informações entre as janelas anônimas do Chrome e as não anônimas, que usam o cache para fazer isso.
Trejkaz
2
O @didibus proxy-revalidateexige que os proxies revalidem sempre em cada acesso. Onde as privateimpede o cache do proxy.
Dan D.
20

RFC 2616, seção 14.9.1 :

Indica que toda ou parte da mensagem de resposta se destina a um único usuário e NÃO DEVE ser armazenada em cache por um cache compartilhado ... Um cache privado (não compartilhado) PODE armazenar em cache a resposta.


Os navegadores podem usar essas informações. Obviamente, o "usuário" atual pode significar muitas coisas: usuário do SO, usuário do navegador (por exemplo, perfis do Chrome) etc. Não está especificado.

Para mim, um exemplo mais concreto de Cache-Control: privateé que servidores proxy (que normalmente têm muitos usuários) não cache-lo. É destinado ao usuário final e a mais ninguém.


Para sua informação, a RFC deixa claro que isso não fornece segurança. Trata-se de mostrar o conteúdo correto, não de protegê-lo.

Esse uso da palavra particular controla apenas onde a resposta pode ser armazenada em cache e não pode garantir a privacidade do conteúdo da mensagem.

Paul Draper
fonte
5
Um cache privado (não compartilhado) PODE armazenar em cache a resposta. Esta parte é fundamental. Obrigado.
1113 Oliver Oliver
0

O campo Expirar entidade-cabeçalho fornece a data / hora após a qual a resposta é considerada obsoleta. O campo Cache-control: maxage fornece o valor da idade (em segundos) maior que a resposta considerada obsoleta.

Embora o campo acima do cabeçalho forneça um mecanismo ao cliente para decidir se deve enviar a solicitação ao servidor. Em algumas condições, o cliente envia uma solicitação para interromper e o valor da idade da resposta é maior que o valor máximo, dose significa que o servidor precisa enviar o recurso ao cliente? Talvez o recurso nunca tenha mudado.

Para resolver esse problema, o HTTP1.1 fornece o cabeçalho modificado pela última vez. O servidor fornece a data da última modificação da resposta ao cliente. Quando o cliente precisar desse recurso, ele enviará o campo de cabeçalho If-Modified-Since para o servidor. Se essa data for anterior à data de modificação do recurso, o servidor enviará o recurso ao cliente e fornecerá o código 200. Caso contrário, ele retornará o código 304 ao cliente e isso significa que o cliente pode usar o recurso em cache.

Lin.Yang
fonte