web-dev-qa-db-fra.com

En-têtes pour empêcher les requêtes 304 / If-modified-since / HEAD

Quels en-têtes dois-je envoyer pour arrêter directement toutes les demandes adressées au serveur après la mise en cache du contenu?

Nous avons un serveur à latence très élevée (Sigh, VMWare), donc même l'envoi d'une requête HEAD au serveur prend + 40ms.

Actuellement, ce sont les en-têtes envoyés/reçus;

Première demande

Client envoie;

GET http://dugong:8080/Rvi24mYJkxFRGNzq73PPvgWGh1j/IMG_2071.jpg HTTP/1.1
Host: dugong:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:9.0) Gecko/20100101 Firefox/9.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Pragma: no-cache, no-cache, no-cache
Cache-Control: no-cache, no-cache, no-cache

Le serveur répond;

HTTP/1.1 200 OK
Server: nginx/1.0.11
Date: Wed, 01 Feb 2012 14:51:51 GMT
Content-Type: text/plain
Vary: Accept-Encoding
Last-Modified: Tue, 31 Jan 2012 10:45:11 GMT
Content-Length: 14
Expires: Thu, 31 Jan 2013 14:51:51 GMT
Cache-Control: max-age=31536000

Donc, il envoie les en-têtes Cache-Control et Expires définis sur 365 jours. Malheureusement, lors de la deuxième actualisation, il demande à nouveau l'objet avec un en-tête If-Modified-Since.

Seconde demande

GET http://dugong:8080/Rvi24mYJkxFRGNzq73PPvgWGh1j/IMG_2071.jpg HTTP/1.1
Host: dugong:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:9.0) Gecko/20100101 Firefox/9.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
If-Modified-Since: Tue, 31 Jan 2012 10:45:11 GMT
Cache-Control: max-age=0

Réponse;

HTTP/1.1 304 Not Modified
Server: nginx/1.0.11
Date: Wed, 01 Feb 2012 14:58:00 GMT
Vary: Accept-Encoding
Expires: Thu, 31 Jan 2013 14:58:00 GMT
Cache-Control: max-age=31536000

Malheureusement, en raison d'un logiciel proxy obsolète et obsolète, nous ne pouvons pas utiliser Keep-Alive, ni placer d'autres serveurs/proxys devant l'application. Nous ne pouvons pas non plus améliorer les performances du serveur et réduire la latence du réseau. J'ai essayé de comprendre quels en-têtes nous pouvons envoyer pour nous débarrasser des 301 demandes. J'ai essayé d'utiliser ETags mais cela ne fait aucune différence, il envoie toujours un en-tête If-modified-since. J'ai également essayé de supprimer l'en-tête Last-Modified mais cela ne provoque qu'une requête GET standard sans mise en cache (Vérifié les journaux, le serveur reçoit toujours des demandes).

Les clients sont un mélange de Firefox (principalement), IE 7, 8 et (certains) 9, Chrome et Safari, mais ce problème semble apparaître dans tous les navigateurs testés.

TL; DR;

Réseau terrible, quels en-têtes devrais-je envoyer pour informer les clients de jamais jamais envoyer des requêtes If-modified-since au serveur pour valider leur cache et conserver le contenu mis en cache jusqu'à ce que l'en-tête Expires devienne rencontré?

Il me manque probablement quelque chose d'évident mais tout ce que j'essaie semble donner les mêmes résultats.

Nous avons un serveur NGINX devant notre serveur d'applications afin que je puisse ajouter/supprimer les en-têtes à ma guise. Notre proxy ne prend pas en charge Keep-Alive et ne constitue en aucun cas un moyen d’améliorer les performances du réseau. En raison d'une conception logicielle épouvantable, l'application Web charge plus de 100 ressources à chaque chargement de page (oui, le logiciel d'entreprise est nul) avec une latence d'environ 40 à 50 ms par objet.

31
Smudge

Vous ne pouvez pas vraiment contrôler les en-têtes que les agents utilisateurs décident de vous envoyer. Si le fichier en question se trouve dans le cache du navigateur et que celui-ci décide de vérifier s'il existe une nouvelle version, il le fera. Selon cet article , voici les situations que les navigateurs demanderont avec If-Modified-Since:

  • L'entrée en cache n'a pas de date d'expiration et le contenu est en cours d'accès pour la première fois dans une session de navigateur.
  • L'entrée mise en cache a une date d'expiration mais elle a expiré
  • L'utilisateur a demandé une mise à jour de page en cliquant sur le bouton Actualiser ou en appuyant sur F5.

Donc, si vous rechargez la page pour tester votre mise en cache, cela ne fonctionnera pas car le navigateur demandera à nouveau les images. Essayez de cliquer sur un lien puis sur un autre lien pour revenir à la première page. Si vos utilisateurs rechargent régulièrement des pages, vous devrez peut-être repenser votre structure de site/d'application pour éviter cela.

Une chose qui peut aider est d'ajouter "public" à l'en-tête de contrôle du cache, c'est-à-dire Cache-Control: public, max-age=31536000. J'ai aussi appris récemment qu'une date d'expiration de plus d'un an est invalide. Étant donné que votre date d'expiration est exactement d'un an, une réduction de quelques jours ou de quelques semaines permettrait peut-être de garantir que le fichier reste dans les caches du navigateur et n'est pas ignoré.

25
DisgruntledGoat

Ce que vous voulez, c'est le mot clé immutable dans votre ligne Cache-Control. Exemple pour php:

header('Cache-Control: public, max-age=80000, immutable');

Source: https://code.facebook.com/posts/557147474482256/this-browser-Tweak-saved-60-of-requests-to-facebook/

5
Zdenek

J'ai eu le même problème, et les demandes frappent définitivement le serveur pour qu'il réponde avec le statut 304 - j'envoie le 304 via du C # et, à coup sûr, il frappe le serveur ..

Je n'avais que Cache-Control: private set. Non max-age et non Expires Il a fonctionné comme prévu; Appuyez sur le serveur avec le If-Modified-Since où je teste la valeur par rapport à ce que j'attends et livre 304 avec un corps de réponse vide - sinon 200 et remplit le corps de la réponse.

La définition de l'en-tête Expires a donné les résultats souhaités, 200 - (from cache) sur le client et aucune demande HTTP n'a été envoyée au serveur.

Mais .. j'ai trouvé que le réglage DEUXmax-age= & Expires peut empêcher les navigateurs d'envoyer un en-tête If-Modified-SinceET ne pas mettre en cache du tout si les valeurs ne correspondent pas .

Ce qu'il faut savoir si vous rencontrez des problèmes de mise en cache et utilisez les différents en-têtes de manière combinée.

3
Andrew Scott

Un peu hors sujet mais peut-être utile. Une autre amélioration pour vos demandes de contenu mis en cache consiste à mettre en cache sessionStorage afin de ne pas avoir à demander au serveur de valider le cache et de recevoir un message 304. Regardez par exemple google, ouvrez la console et écrivez sessionStorage. Vous verrez qu'ils mettent en cache CSS ou DOM avec le sessionStorage. ofc, vous ne pouvez pas utiliser cela dans les anciens navigateurs IE.

1
Pablo Estornut

Examinez votre code source et assurez-vous qu'il n'y a pas de META REFRESH pour passer à une autre page. Utilisez quelque chose comme sendRedirect à la place. Sur ma configuration, META REFRESH produit 304s dans IE, mais pas Chrome. sendRedirect ne le produit pas sur les deux navigateurs.

<meta http-equiv="refresh" content="0;URL='nextpage'" />    

contre

<% response.sendRedirect("nextpage") %>
0
Richard Sandoz