web-dev-qa-db-fra.com

Faire IE mettre en cache les ressources mais toujours revalider

L'en-tête de contrôle de cache "no-cache, must-revalidate, private" permet aux navigateurs de mettre en cache la ressource mais force une revalidation avec des requêtes conditionnelles. Cela fonctionne comme prévu dans FF, Safari et Chrome.

Cependant, IE7 + 8 n'envoie pas de demande conditionnelle, c'est-à-dire que "If-Modified-Since" est manquant dans l'en-tête de la demande et donc le serveur répond avec HTTP/200 au lieu de HTTP/304.

Voici les en-têtes de réponse complets du serveur:

Last-Modified: Wed, 16 Feb 2011 13:52:26 GMT
Content-type: text/html;charset=utf-8
Content-Length: 10835
Date: Wed, 16 Feb 2011 13:52:26 GMT
Connection: keep-alive
Cache-Control: no-cache, must-revalidate, private

Cela ressemble à un bug IE, mais je n'ai rien trouvé de similaire sur le web, donc je me demande si peut-être l'absence ou l'existence d'un autre en-tête fait IE = se comporte étrangement?

Une bonne discussion de la différence entre no-cache et max-age: Quelle est la différence entre Cache-Control: max-age = 0 et no-cache?

43
alienhard

Je l'ai finalement compris. Voici une explication et une solution testée.

Le site suivant confirme mon observation: http://blog.httpwatch.com/2008/10/15/two-important-differences-between-firefox-and-ie-caching/

Il indique que IE ne stocke pas localement les pages avec la directive "no-cache" et envoie donc toujours une demande inconditionnelle.

Il existe également un article de support MS - https://support.Microsoft.com/help/234067/ - qui confirme cela:

"Internet Explorer prend en charge l'en-tête HTTP 1.1 Cache-Control, qui empêche toute mise en cache d'une ressource Web particulière lorsque la valeur sans cache est spécifiée ..."

Ce comportement n'est pas entièrement faux - mais ce n'est pas ce que la RFC 2616 (sec. 14.9.1) voulait. À propos de 'no-cache', il dit "... un cache NE DOIT PAS utiliser la réponse pour satisfaire une demande ultérieure sans une revalidation réussie avec le serveur d'origine." La réponse PEUT donc être mise en cache mais DOIT la revalider. Les principaux navigateurs, à l'exception d'IE, mettent en cache la réponse et la revalident. Pour éviter de stocker la demande, il existe la directive Cache-Control "no-store".

En résumé, IE traite 'no-cache' comme 'no-store'.

Et voici la solution pour activer les requêtes conditionnelles pour IE et les autres navigateurs de manière cohérente:

N'utilisez pas de non-cache, mais définissez plutôt l'en-tête Expires sur le passé (ou -1, ce qui a le même effet). IE, ainsi que les autres principaux navigateurs, enverra alors des demandes conditionnelles. (Remarque, vous devez également être conscient du IE bogue d'en-tête variable, qui empêche la mise en cache.)

Ce sont les champs d'en-tête critiques:

Last-Modified: Wed, 16 Feb 2011 13:52:26 GMT
Expires: -1
Cache-Control: must-revalidate, private
  • Last-Modified (ou ETag) est nécessaire comme validateur
  • Expire -1 indique que la ressource est périmée et doit être revalidée
  • Cache-Control ne doit pas inclure de no-cache ou no-store
74
alienhard