Bonjour,

Voila je rencontre un petit problème avec mon code.

Ce que je fais

En fait j'aimerais comprendre comment gérer le cache des navigateurs avec mon code PHP.
J'aimerais que lorsque je modifie mon application le cache navigateur soit regénéré.

Il y a plein de directives HTTP tels que :

Expires: Thu, 21 Jul 1977 07:30:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0
Last-Modified: Thu, 21 Jul 1977 07:30:00 GMT
Pragma: no-cache

A l'heure actuelle j'injecte ce code :

header('Expires: Thu, 21 Jul 1977 07:30:00 GMT');
header("Cache-Control: no-store, no-cache, must-revalidate");
header('Cache-Control: post-check=0, pre-check=0', false);
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header('Pragma: no-cache');
header('Content-type: text/html; charset=UTF-8');

Cela devrait avoir pour but de désactiver complètement le cache mais cela marche moyen avec les derniers navigateurs en date.

Ce que je veux

J'aimerais bien que quelqu'un m'explique à quoi servent chacunes d'entres elles et comment les utilisers correctement avec la fonction header() dans nos application PHP.

J'aimerais utiliser le cache des navigateur et lorsque m'on application est modifiée que l'utilisateur final n'est pas besoin de faire F5 pour voir les modifications appliquées à la page. (Un simple connexion à la page n'affiche pas les modifications, l'utilisateur est obligé de faire F5 pour les voirs (images, css)).

Peut être cela peut il faire l'objet d'un prochain tutoriel Grafikart :p ?

Merci d'avance à vous en tout cas ;)

++

13 réponses


Ton code met à jour la cache en permanence pour la partie HTML par contre pour le CSS / JS et le reste, ça se fait via la conf apache ou nginx

Ok merci.
Que faut il mettre dans la conf de apache pour qu'il envoi l'entête au navigateur comme quoi le fichier js/css ou image a été modifié ?

Là regarde sur google je n'ai plus du tout la syntaxe en tête et la liste des ressources à filtrer est longue comme le bras

Un petit bout de code qui pourrais t'aider (à mettre dans ton .htaccess) :

## contrôle du cache navigateur - Expire headers
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresDefault "access plus 7200 seconds"
    ExpiresByType image/jpg             "access plus 1 week"
    ExpiresByType image/jpeg            "access plus 1 week"
    ExpiresByType image/png             "access plus 1 week"
    ExpiresByType image/gif             "access plus 1 week"
    ExpiresByType image/svg+xml         "access plus 1 week"
    AddType image/x-icon .ico
    ExpiresByType image/ico             "access plus 1 week"
    ExpiresByType image/icon            "access plus 1 week"
    ExpiresByType image/x-icon          "access plus 1 week"
</IfModule>

<IfModule mod_headers.c>

    <FilesMatch "\\.(ico|jpe?g|png|gif|swf)$">
        Header set Cache-Control "max-age=2592000, public"
    </FilesMatch>

</IfModule>

Merci !

Dans ce cas le navigateur va garder le cache pendant 1 semaine sur les fichiers images.
Mais que va-t-il se passer si je modifie un fichier avant la période d'1 semaine ?

L'image sera-t-elle actualisé immédiatement par le navigateur lors de la modification de l'image ou le navigateur attendra le délai d'1 semaine avant d'actualiser l'image ?

Par défaut le navigateur garderas le fichier en cache pendant 7200 secondes :

ExpiresDefault "access plus 7200 seconds"

Si tue le modifie avant il seras aussi modifier pour le client aprèsj'ai mis d'autre règle pour les images.

Ok et ça tu le déploie au niveau du fichier httpd.conf ? C'est mieux non ?

Je viens de faire le test et cela ne fonctionne pas :(

J'ai ajouté toutes les règles dans le fichier httpd.conf et j'ai activé en même temps le module expires et headers.

J'ai chargé une page qui affiche une image logotest.png depuis mon navigateur.

J'ai remplacé le fichier logotest.png par une autre image ayant le même nom sur le serveur et j'ai ouvert un autre onglet sur mon navigateur et je me suis rendu sur la même url. L'image dans le navigateur n'a pas été actualisé, j'ai toujours l'ancienne image.

Si je fais F5 sur la page, l'image change et est correctement actualisé.

J'aimerais que le navigateur détecte lorsque le fichier sur le serveur a été modifié et l'affiche à l'utilisateur sans que l'utilisateur est à faire F5 pour actualiser le cache.

J'ai utilisé IE 11 pour faire les tests.

Utiliser l'Etag ne serait pas mieux pour invalider les fichiers lors de modification ?

Comment ça ?

Tu peux aussi générer des fingerprint
/css/global.css?1309495796
basé soit sur la date soit sur un md5

C'est ce que je fais déjà pour les fichiers css et js. Mais par contre pour les images si je dois le faire pour toutes les images :s

Pour les images : le jour où tu modifies une image, tu changes sont nom
L'idée est bien d'avoir une uri qui correspond exactement au fichier et à sa version
du coup on peut mettre un max-age très élévé et pas besoin de must-revalide