Come impedire la cache del browser per il sito php


121

Ho un sito php in esecuzione nel server cloud. Ogni volta che aggiungo nuovi file css, js o immagini, il browser carica gli stessi vecchi file js, css e immagine memorizzati nella cache.

Il mio sito ha un doctype e un meta tag come di seguito

<!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)">

A causa del doctype e del meta codice sopra, sto caricando gli stessi file memorizzati nella cache nel browser invece di uno nuovo


No Cache in all Browsers. Puoi anche eseguire un? RandomGeneratedNumber sui file che non desideri vengano memorizzati nella cache.
Kodemon

2
Probabilmente non si vuole disabilitare la cache completamente per le immagini / js / css: stackoverflow.com/questions/4206224/...
FoolishSeth

Ha resistito alla tentazione di necro, ma per favore, chiunque lo consideri: fermati. Impara a controllare e utilizzare il caching, non disabilitarlo ciecamente a causa di un episodio scomodo. Leggi il capitolo sulla memorizzazione nella cache da HTTP The Definitive Guide - questo libro (e le RFC) dovrebbe essere una lettura obbligatoria, con un test. Scopri come specificare Last-Modified, rispondere a If-Modified-Since e utilizzare l'identificazione ETag. Quindi, quando l'asset viene aggiornato, i browser verranno informati quando quel 304 diventa di nuovo 200.
amcgregor

Risposte:


283

prova questo

<?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");
?>

6
Ad eccezione di "max-age = 0", quelle sono le intestazioni inviate da PHP senza specificare quanto sopra nella mia installazione .. Sembra che PHP cerchi di impedire il caching del browser per impostazione predefinita ...
fast-reflexes

1
Ho un plugin per WordPress che invia un tema alternativo alle vecchie versioni di Internet Explorer e si è verificato un errore con alcuni sistemi di memorizzazione nella cache. Questo post è apparso durante la mia prima ricerca su Google. Ben fatto.
Imperativo

3
Tieni presente che questo non può essere incorporato all'interno di html; dovrebbe essere in cima alla pagina.
Hunter S

9
Nota: se lo usi session_start()successivamente, sovrascriverà l'intestazione con Cache-Control: private, max-age=10800, pre-check=10800perché 180 minuti è il valore predefinito di session.cache_expire. Se non puoi evitare di avviare la sessione, ma devi disabilitare l'uso della cache session_cache_limiter('private');session_cache_expire(0);.
mgutt

2
@thdoan Il secondo parametro della headerfunzione è un booleano per la sostituzione . Il parametro di sostituzione facoltativo indica se l'intestazione deve sostituire un'intestazione simile precedente o aggiungere una seconda intestazione dello stesso tipo.
mrReiha

36

Qui, se vuoi controllarlo tramite HTML: fai come sotto Opzione 1:

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

E se vuoi controllarlo tramite PHP: fallo come sotto Opzione 2:

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 l' opzione 2 È SEMPRE MIGLIORE per evitare problemi di cache basata su proxy.


10

Puoi provare questo:

    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");

Si spera che aiuti a prevenire la cache, se presente!


Questo riguarda solo la memorizzazione nella cache dei file HTML, giusto? E non ha niente a che fare con l'eTag? Grazie!
Sam Levin

4
solo la prima riga dovrebbe essere sufficiente. La quinta riga è effettivamente sbagliata e non ha nulla a che fare in una risposta del server (è un'intestazione di richiesta). la sesta riga non avrà alcun effetto.
Potrei

L'avvicinamento del fucile: lancia tutto contro il muro, spero che qualcosa si attacchi. Secondo il mio commento sulla domanda stessa, consiglio vivamente di prendere una copia di HTTP: The Definitive Guide e di leggere il capitolo sul Caching. Anche le RFC, ma leggerle è un'abilità distinta. ("Connection: close" è un divertente foot-shot da includere, disabilitare il pipelining efficiente delle richieste, o non farà nulla, ma sospetto che PHP potrebbe effettivamente lasciarlo passare.)
amcgregor

7

Ho avuto problemi con la memorizzazione nella cache dei miei file css. L'impostazione delle intestazioni in PHP non mi ha aiutato (forse perché le intestazioni dovrebbero essere impostate nel file del foglio di stile invece della pagina che vi si collega?).

Ho trovato la soluzione in questa pagina: https://css-tricks.com/can-we-prevent-css-caching/

La soluzione:

Aggiungi timestamp come parte della query dell'URI per il file collegato.
(Può essere utilizzato per css, js, immagini ecc.)

Per lo sviluppo:

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

Per la produzione (dove la memorizzazione nella cache è principalmente una buona cosa):

<link rel="stylesheet" type="text/css" href="style.css?version=3.2">
(e riscrivi manualmente quando è necessario)

O una combinazione di questi due:

<?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') : ""; ?>">

MODIFICARE:

O una combinazione più carina di questi due:

<?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(); ?>">

Versioni arbitrarie, timestamp attuali (sconfiggere completamente il caching) ... ma non l'unica cosa che effettivamente ha senso e funziona, indipendentemente da un flag di "debug" o meno. Perché non stai usando l'mtime effettivo del file? Quindi non avresti letteralmente mai bisogno di aggiornare il PHP e le cache non diventerebbero completamente e fantasticamente inutili. Oppure fornisci le tue statistiche con un server HTTP configurato correttamente come Nginx o Apache che imposta un Last-Modified e ETag adeguati. Allo stesso modo, quel tipo di flag "debugging" esiste già ... nel browser. (Disabilita cache, aggiorna senza cache, svuota cache, ...)
amcgregor

5

Impedire la cache del browser non è una buona idea a seconda dei casi. Cercando una soluzione ho trovato soluzioni come questa:

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

il problema qui è che se il file viene sovrascritto durante un aggiornamento sul server, che è il mio scenario, la cache viene ignorata perché il timestamp viene modificato anche il contenuto del file è lo stesso.

Uso questa soluzione per forzare il browser a scaricare le risorse solo se il suo contenuto viene modificato:

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

Yikes! Sarebbe terribile per prestazioni e scalabilità caricare sempre tutti i tuoi file CSS / JS nel thread principale per controllarne la dimensione / hash.
Dalin

@Dalin Prima di piangere le lacrime di Gentoo ricer (una distribuzione Linux nota per "andare veloce" essendo eccessivamente compilata dai sorgenti e ottimizzata per l'architettura), timbrerei una statchiamata. Senza cache del file system, 16ns, massimo? Con cache, in modo affidabile <8ns. Nanosecondi. E sul mio sistema MD5 può elaborare 754 MiB / s senza lampeggiare. ( openssl speed md5) Combinato, un file CSS da 100 KB avrebbe un overhead aggiuntivo combinato di… 129 µs (microsecondi, 0,1295 ms) + 8 ns (che non contribuisce in modo significativo al numero finale) = 129 µs.
amcgregor

Dopo ulteriori considerazioni, mi sorprende che l'unica risposta "corretta" (con il minimo onere di manutenzione, un comportamento più accurato / affidabile) sia sia la meno votata, sia respinta in un singolo commento su basi così inconsistenti e irrealistiche.
amcgregor

Probabilmente io e te lavoriamo su diversi siti web. Ma resto fedele al mio commento. Se ci sono dozzine di thread simultanei che forniscono pagine Web in qualsiasi momento, penso che ci siano opzioni migliori di cui non avrai nemmeno bisogno di chiederti se è scalabile. hash_file('md5', $deployment_counter)o hash_file('md5', $cache_clear_counter)sono i primi che mi vengono in mente.
Dalin
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.