Como impedir o cache do navegador para o site php

120

Eu tenho um site php em execução no servidor de nuvem. Sempre que adiciono novos arquivos css, js ou imagens, o navegador carrega os mesmos arquivos js, css e de imagem antigos armazenados no cache.

Meu site tem um doctype e uma meta tag, conforme abaixo

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  <meta http-equiv="Page-Enter" content="blendTrans(Duration=1.0)">
  <meta http-equiv="Page-Exit" content="blendTrans(Duration=1.0)">
  <meta http-equiv="Site-Enter" content="blendTrans(Duration=1.0)">
  <meta http-equiv="Site-Exit" content="blendTrans(Duration=1.0)">

Por causa do doctype e do meta-código acima, estou carregando os mesmos arquivos armazenados em cache no navegador em vez de um novo

ArrayOutOfBound
fonte
No Cache in all Browsers. Você também pode fazer um? RandomGeneratedNumber nos arquivos que não deseja que sejam armazenados em cache.
Kodemon
2
Você provavelmente não deseja desativar o cache completamente para images / js / css: stackoverflow.com/questions/4206224/…
FoolishSeth
Resistiu à tentação de necro, mas por favor, qualquer um considerando isso: pare. Aprenda a controlar e usar o cache, não apenas o desative cegamente por causa de um episódio inconveniente. Leia o capítulo sobre Cache do HTTP O Guia Definitivo - este livro (e as RFCs) deve ser uma leitura obrigatória, com um teste. Aprenda a especificar o Last-Modified, responda a If-Modified-Since e utilize a identificação ETag. Então, quando o ativo for atualizado, os navegadores serão informados quando o 304 se tornar um 200 mais uma vez.
amcgregor 26/06

Respostas:

282

tente isso

<?php

header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
?>
Codesen
fonte
6
Com exceção de "max-age = 0", esses são os cabeçalhos enviados pelo PHP sem especificar o acima em minha instalação .. Parece PHP tenta impedir o cache do navegador por padrão ...
fast-reflexos
1
Eu tenho um plug-in do WordPress que envia um tema alternativo para versões antigas do Internet Explorer e estava ficando muito desarranjado em alguns sistemas de cache. Este post surgiu na minha primeira pesquisa no Google. Bem jogado.
imperativo
3
Lembre-se de que isso não pode ser incorporado dentro do html; isso deve estar no topo da página.
Hunter S
9
Nota: Se você usar session_start()posteriormente, ele substituirá o cabeçalho Cache-Control: private, max-age=10800, pre-check=10800porque 180 minutos é o valor padrão de session.cache_expire. Se você não puder evitar o início da sessão, mas precisará desativar o uso do cache session_cache_limiter('private');session_cache_expire(0);.
mgutt
2
@ thdoan O segundo parâmetro da headerfunção é um booleano para substituir . O parâmetro opcional replace indica se o cabeçalho deve substituir um cabeçalho semelhante anterior ou adicionar um segundo cabeçalho do mesmo tipo.
MrReiha 08/12/19
36

Aqui, se você deseja controlá-lo através de HTML: faça como abaixo a Opção 1:

<meta http-equiv="expires" content="Sun, 01 Jan 2014 00:00:00 GMT"/>
<meta http-equiv="pragma" content="no-cache" />

E se você deseja controlá-lo através do PHP: faça como na opção 2 abaixo :

header('Expires: Sun, 01 Jan 2014 00:00:00 GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', FALSE);
header('Pragma: no-cache');

E a opção 2 SEMPRE É MELHOR para evitar problemas de cache com base em proxy.

Ritesh Aryal
fonte
10

Você pode tentar isso:

    header("Expires: Tue, 03 Jul 2001 06:00:00 GMT");
    header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
    header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
    header("Cache-Control: post-check=0, pre-check=0", false);
    header("Pragma: no-cache");
    header("Connection: close");

Espero que ajude a impedir o cache, se houver!

Aakanksha
fonte
Isso refere-se apenas ao cache dos arquivos HTML, certo? E não tem nada a ver com a eTag? Obrigado!
Sam Levin
4
apenas a primeira linha deve bastar perfeitamente. A 5ª linha está realmente errada e não tem nada a ver em uma resposta do servidor (é um cabeçalho de solicitação). sexta linha não terá nenhum efeito. Eu poderia continuar ...
The Surrican
A abordagem da espingarda: jogue tudo na parede, espero que algo fique. Conforme meu comentário sobre a pergunta em si, eu recomendo pegar uma cópia do HTTP: The Definitive Guide e ler o capítulo sobre Cache. Também os RFCs, mas a leitura deles é uma habilidade distinta. ("Connection: close" é uma cena hilariante para incluir, desabilitando o pipelining eficiente de solicitações ou não fará nada, mas eu suspeito que o PHP possa realmente deixar isso passar.)
amcgregor 26/06
7

Eu tive um problema com o cache dos meus arquivos CSS. Definir cabeçalhos no PHP não me ajudou (talvez porque os cabeçalhos precisassem ser configurados no arquivo de folha de estilo em vez da página vinculada a ele?).

Encontrei a solução nesta página: https://css-tricks.com/can-we-prevent-css-caching/

A solução:

Anexar carimbo de data e hora como a parte da consulta do URI para o arquivo vinculado.
(Pode ser usado para css, js, imagens etc.)

Para desenvolvimento:

<link rel="stylesheet" href="style.css?<?php echo date('Y-m-d_H:i:s'); ?>">

Para produção (onde o cache é principalmente uma coisa boa):

<link rel="stylesheet" type="text/css" href="style.css?version=3.2">
(e reescreva manualmente quando necessário)

Ou combinação destes dois:

<?php
    define( "DEBUGGING", true ); // or false in production enviroment
?>
<!-- ... -->
<link rel="stylesheet" type="text/css" href="style.css?version=3.2<?php echo (DEBUGGING) ? date('_Y-m-d_H:i:s') : ""; ?>">

EDITAR:

Ou uma combinação mais bonita desses dois:

<?php
    // Init
    define( "DEBUGGING", true ); // or false in production enviroment
    // Functions
    function get_cache_prevent_string( $always = false ) {
        return (DEBUGGING || $always) ? date('_Y-m-d_H:i:s') : "";
    }
?>
<!-- ... -->
<link rel="stylesheet" type="text/css" href="style.css?version=3.2<?php echo get_cache_prevent_string(); ?>">
Lukas
fonte
Versões arbitrárias, carimbos de data / hora atuais (derrotando completamente o cache) ... mas não a única coisa que realmente faz sentido e funciona, independentemente de um sinalizador de "depuração" ou não. Por que você não está usando o mtime real do arquivo? Então você literalmente nunca precisaria atualizar o PHP, e os caches não se tornariam completamente e fantasticamente inúteis. Ou apenas entregue sua estática com um servidor HTTP configurado corretamente, como Nginx ou Apache, que define um Last Modified e ETag adequados. Da mesma forma, esse tipo de sinalizador de "depuração" já existe ... no navegador. (Desabilitar caches, atualizar sem cache, caches vazios, ...)
amcgregor
5

Impedir que o cache do navegador não seja uma boa ideia, dependendo do caso. Procurando uma solução, encontrei soluções como esta:

<link rel="stylesheet" type="text/css" href="meu.css?v=<?=filemtime($file);?>">

o problema aqui é que, se o arquivo for substituído durante uma atualização no servidor, que é o meu cenário, o cache será ignorado porque o carimbo de data / hora é modificado, mesmo o conteúdo do arquivo é o mesmo.

Eu uso esta solução para forçar o navegador a baixar ativos somente se seu conteúdo for modificado:

<link rel="stylesheet" type="text/css" href="meu.css?v=<?=hash_file('md5', $file);?>">
ismavolk
fonte
Caramba! Seria péssimo para o desempenho e a escalabilidade estar sempre carregando todos os seus arquivos CSS / JS no thread principal para verificar seu tamanho / hash.
Dalin 5/03
@ Dalin Antes de chorar as lágrimas do Gentoo Ricer (uma distribuição Linux conhecida por "ir rápido" por ser excessivamente compilada a partir da fonte e da arquitetura), eu marcava uma statligação. Sem cache do sistema de arquivos, 16ns, no máximo? Com cache, com confiabilidade <8ns. Nanossegundos. E no meu sistema, o MD5 pode processar 754 MiB / s sem piscar. ( openssl speed md5) Combinado, um arquivo CSS de 100 KB teria uma sobrecarga adicional combinada de… 129µs (microssegundos, 0,1295ms) + 8ns (o que não contribui significativamente para o número final) = 129µs.
amcgregor 26/06
Após uma análise mais aprofundada, me surpreende que a única resposta "correta" (com menor carga de manutenção, comportamento mais preciso / confiável) seja a menos votada e descartada em um único comentário por motivos tão frágeis e irrealistas.
amcgregor 26/06
Você e eu provavelmente trabalhamos em sites diferentes. Mas eu mantenho meu comentário. Se houver dezenas de threads simultâneos entregando páginas da Web a qualquer momento, acho que há opções melhores que você nem precisará questionar se é escalável. hash_file('md5', $deployment_counter)ou hash_file('md5', $cache_clear_counter)são os primeiros que vêm à mente.
Dalin