Pourquoi le navigateur n'envoie pas de “Si-None-Match” en-tête?
Je suis en train de télécharger (et, espérons-le cache) une image chargée dynamiquement en PHP. Voici les en-têtes envoyés et reçus:
Demande:
GET /url:resource/Pomegranate/resources/images/logo.png HTTP/1.1
Host: pome.local
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Ubuntu Chromium/25.0.1364.160 Chrome/25.0.1364.160 Safari/537.22
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: PHPSESSID=fb8ghv9ti6v5s3ekkmvtacr9u5
Réponse:
HTTP/1.1 200 OK
Date: Tue, 09 Apr 2013 11:00:36 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.3.14 ZendServer/5.0
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Disposition: inline; filename="logo"
ETag: "1355829295"
Last-Modified: Tue, 18 Dec 2012 14:44:55 Asia/Tehran
Keep-Alive: timeout=5, max=98
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: image/png
Lorsque j'ajoute l'URL, exactement les mêmes en-têtes sont envoyés et reçus. Ma question est que dois-je envoyer ma réponse pour voir la If-None-Match
en-tête de la demande conséquente?
NOTE: je crois que les en-têtes ont été faites tout à l'amende n'y a pas longtemps, même si je ne peux pas être sûr, mais je pense que les navigateurs sont modifiées de ne pas l'envoyer à la If-None-Match
en-tête de plus (j'ai utilisé de voir que d'en-tête). Je suis en essais avec Chrome et Firefox, et les deux ne parviennent pas à envoyer l'en-tête.
Last-Modified: Tue, 18 Dec 2012 …
etExpires: Thu, 19 Nov 1981 08:52:00 GMT
se contredisent un peu, vous ne pensez pas?- C'est parce que je veux faire en sorte qu'il n'est pas mis en cache dans le navigateur. Je viens de régler le
Expires
égal àLast-Modified
et obtenu le même résultat. - Au tout début de votre question, vous dites que vous voulez mise en cache, et maintenant vous n'avez pas?
- Je suis en train de mettre en œuvre un reverse proxy cache système, pour cela j'ai besoin pour s'assurer que le navigateur ne cache rien localement. Il devrait plutôt demander serveur web de ressources à chaque fois qu'il a besoin d'eux tout en présentant la version de sa propre copie en cours (si elle en a un). Le navigateur est censé envoyer des ressources " de la version actuelle par le biais de ` mais il ne le fait pas. Qui résultats dans le téléchargement de ressources à chaque fois. Mais, si le navigateur réussit à envoyé la ressource version, PHP peut dire si il est nécessaire de mettre à jour la ressource sinon il enverra "304" en-tête qui indique au navigateur d'utiliser sa version mise en cache.
- Désolé, mais il me semble que si vous êtes juste de mélanger tout type d'en-tête que vous pouvez penser, sans aucune logique. Vous dites
Cache-Control: no-store, no-cache
– mais attendez-vous de la mise en cache se passer? - Peut-être que vous avez raison. Maintenant que j'y pense, ceux
Cache-Control
les en-têtes doivent provoquer le problème. Le truc, c'est que je n'ai pas les envoyer. Ils doivent être générés automatiquement. permettez-moi de voir si je peux l'empêcher d'être envoyé. - Merci beaucoup, ça a fonctionné. Pourriez-vous nous faire l'honneur d'envoyer une réponse (pour l'enregistrement)?
- C'est vraiment stupide, mais je viens de passer 4 heures à la mise en œuvre de cette aide de différentes méthodes dans mon .NET Web Api, tout pour réaliser mon chrome dev tools a la mise en cache désactivé. Assurez-vous que vous désactivez cette fonction pour tester cela en Chrome!!!
Vous devez vous connecter pour publier un commentaire.
Vos en-têtes de réponse comprennent
Cache-Control: no-store, no-cache
; ces empêcher la mise en cache.Supprimer ces valeurs (je pense que
must-revalidate, post-check=0, pre-check=0
pourrait/devrait être gardé – ils dire au navigateur de vérifier avec le serveur si il y a un changement).Et je m'en tiendrais à
Last-Modified
seul (si les modifications apportées à vos ressources peuvent être détectés à l'aide de ce critère à lui seul) –ETag
est une chose plus compliquée à gérer (surtout si vous voulez traiter avec elle dans votre script PHP vous-même), et Google PageSpeed/YSlow conseiller contre cette trop.Cache-Control
de la tête de générer automatiquement sans que je sache. J'ai utilisé PHP header_remove pour arrêter les en-têtes avant de commencer l'envoi de mon propre. Merci beaucoup.Même Problème, Solution Similaire
J'ai été d'essayer de déterminer pourquoi Google Chrome n'enverrons pas de
If-None-Match
en-têtes lors de la visite d'un site que je suis en train d'élaborer. (Chrome 46.0.2490.71 m, bien que je ne suis pas sûr de la pertinence de la version.)C'est une façon différente, bien que très similaire — réponse de l'OP, finalement, cité dans un commentaire au sujet de la Accepté de Répondre), mais il traite du même problème:
Le navigateur n'envoie pas le
If-None-Match
d'en-tête dans les demandes ultérieures "quand il le faut" (c'est à dire, une logique côté serveur, via PHP ou similaire, a été utilisé pour envoyer unETag
ouLast-Modified
d'en-tête dans la première réponse).Conditions préalables
À l'aide d'un auto-signé certificat TLS, qui tourne le verrou rouge en Chrome, les changements de google Chrome comportement de mise en cache. Avant de tenter de résoudre un problème de cette nature, installer le certificat auto-signé dans la banque de Racine de Confiance, et de redémarrer complètement le navigateur, comme l'explique l' https://stackoverflow.com/a/19102293 .
1er Épiphanie: Si-None-Match exige un ETag à partir du serveur, premier
Je me suis rendu compte assez rapidement que Chrome (et probablement les la plupart ou tous les autres navigateurs) de ne pas envoyer un
If-None-Match
en-tête jusqu'à ce que le serveur a déjà envoyé unETag
- tête en réponse à une demande précédente. Logiquement, c'est parfaitement logique; après tout, comment pourrait-Chrome envoyerIf-None-Match
lorsqu'il n'est jamais été donné de la valeur?Cela m'amener à regarder ma logique côté serveur — en particulier, comment les en-têtes sont envoyés quand je veux le user-agent pour mettre en cache la réponse — dans un effort pour déterminer pour quelle raison le
ETag
- tête n'est pas envoyé en réponse à google Chrome de la première demande de la ressource. J'avais fait un effort calculé pour inclure leETag
d'en-tête dans ma logique de l'application.M'arrive d'être en utilisant PHP, donc @Mehran (l'OP) commentaire a sauté hors de moi (il/elle dit que l'appel
header_remove()
avant d'envoyer le désiré lié au cache-têtes résout le problème).Franchement, j'étais sceptique à propos de cette solution, parce que a) je suis presque sûr que PHP ne pas envoyer les en-têtes de ses propres par défaut (et il n'a pas, compte tenu de ma configuration); et b) lorsque j'ai appelé
var_dump(headers_list());
juste avant de mettre mon custom de la mise en cache des en-têtes en PHP, la seule tête de série a été l'une que j'ai été la mise intentionnellement juste au-dessus:Donc, n'ayant rien à perdre, j'ai essayé d'appeler
header_remove();
juste avant l'envoi de mon en-têtes personnalisés. Et à ma grande surprise, PHP a commencé à envoyer de l'ETag
- tête tout d'un coup!2e Épiphanie: gzipping les changements de réponse de son hachage
Puis, il me m'a frappé comme un sac de briques: en spécifiant le
Content-type
header en PHP, je parlais de NGINX (le serveur que j'utilise) pour GZIP la réponse, une fois PHP mains en arrière de NGINX! Pour être clair, laContent-type
que j'étais en précisant était sur NGINX la liste des types de gzip.Pour la perfection, mon NGINX GZIP paramètres sont définis comme suit, et PHP est câblé pour NGINX via php-fpm:
J'ai réfléchi à pourquoi NGINX peut supprimer le
ETag
que j'avais envoyé en PHP quand un "gzippable" content-type est spécifié, et est venu avec une réponse évidente: parce que NGINX modifie le corps de la réponse que PHP passe en arrière quand NGINX fichiers gzip il! Cela fait beaucoup de sens; il n'y a pas de point dans l'envoi de laETag
quand ça ne va pas correspondre à la réponse utilisé pour les générer. C'est assez noire qui NGINX gère ce scénario est si intelligemment.Je ne sais pas si NGINX a toujours été assez intelligent pour ne pas compresser la réponse des organismes qui sont non compressé, mais contiennent
ETag
les en-têtes de, mais cela semble être ce qui se passe ici.Mise à JOUR: j'ai trouvé commentaire qui explique NGINX du comportement à cet égard, qui cite deux de riches discussions à ce sujet:
Posted on Jun 15, 2013 by Massive Bird
.Dans l'intérêt de la préservation de ce précieux explication, s'il arrive à disparaître, je cite
Massive Bird
contribution à la discussion:Cependant, NGINX du comportement à cet égard pourrait être considéré comme un peu imparfait en ce que le même spec
Je ne suis pas sûr de NGINX actuelle de disposition à cet égard, et en particulier, si oui ou non il a ajouté le support pour les "faibles" les Etags.
Alors, Quelle est la Solution?
Alors, quelle est la solution pour obtenir
ETag
de nouveau dans la réponse? Faire le gzipping en PHP, de sorte que NGINX voit que la réponse est déjà compressé, et tout simplement de passe ainsi que, tout en laissant laETag
en-tête intacte:Une fois que j'ai ajouté à cet appel avant d'envoyer les en-têtes et le corps de la réponse, PHP a commencé à envoyer de l'
ETag
valeur à chaque réponse. Oui!Autres Leçons Apprises
Voici quelques détails intéressants glanés au fil de mes recherches. Cette information est plutôt pratique lorsque l'on tente de tester un serveur de mise en cache côté mise en œuvre, que ce soit en PHP ou un autre langage.
Chrome, et de ses Outils de développement "Net" du panneau, de se comporter différemment en fonction de la façon dont la demande est initiée.
Si la demande est "frais", par exemple, en appuyant sur
Ctrl+F5
, Chrome envoie ces en-têtes:et le serveur répond
200 OK
.Si la demande est faite avec seulement
F5
, Chrome envoie ces en-têtes:et le serveur répond
304 Not Modified
.Enfin, si la demande est faite en cliquant sur un lien de la page que vous êtes en train de visualiser, ou mettant l'accent sur Chrome la barre d'adresse et en appuyant sur Entrée, Chrome envoie ces en-têtes:
et le serveur répond
200 OK (from cache)
.Alors que ce comportement un peu déroutant au premier abord, si vous ne savez pas comment il fonctionne, il est idéal de comportement, parce qu'il permet de tester tous les possible de requête/réponse scénario très bien.
Peut-être le plus déroutant, c'est que Chrome insère automatiquement le
Cache-Control: no-cache
etPragma: no-cache
les en-têtes dans le sortant du demande alors qu'en fait, Chrome est d'acquérir les réponses de son cache (comme en témoignent les200 OK (from cache)
réponse).Cette expérience a été plutôt instructif pour moi, et j'espère que d'autres trouvent cette analyse de la valeur dans le futur.
Cache-Control: no-cache
en-tête, et a enfin trouvé le problème est que peu de case à cocher.... soupirAffichage pour de futures moi...
J'ai eu un problème similaire, j'ai été l'envoi
ETag
dans la réponse, mais le client HTTP n'était pas l'envoi d'unIf-None-Match
d'en-tête dans les requêtes suivantes (ce qui est étrange parce que c'était le jour avant).S'avère que j'ai été en utilisant
http://localhost:9000
pour le développement (ce qui ne l'utilisez pasIf-None-Match
) - par mise àhttp://127.0.0.1:9000
Chrome1 automatiquement commencé l'envoi de laIf-None-Match
en-tête de demande à nouveau.En outre - assurer
Devtools > Network > Disable Cache [ ]
n'est pas cochée.Chrome: Version 71.0.3578.98 (compilation Officiel) (64-bit)
1 je ne peux pas trouver n'importe où, cela est documenté - je suis en supposant que Chrome était responsable de cette logique.
Ce qui m'est arrivé, grâce à 2 raisons:
Mon serveur n'envoie pas etag en-tête de réponse. J'ai mis à jour mon jetty web.xml pour revenir etag par adjonction de ce qui suit:
L'URL que j'ai appelé a pour fichier xml. Quand je l'ai changé pour un fichier html, chrome a commencé à envoyer des "si-none-match" en-tête de!
J'espère que cela aide quelqu'un
Problème similaire
J'essayais d'obtenir Conditionnelle requête GET avec
If-None-Match
en-tête, avoir fourni la bonneEtag
en-tête, mais en vain, dans n'importe quel navigateur, j'ai essayé.Après beaucoup d'essais je me rends compte que les navigateurs traiter les deux
GET
etPOST
le même chemin que d'un cache même candidat. Ayant ainsiGET
avec une bonneEtag
a été effectivement annulé avec effet immédiat "POST" dans le même chemin avecCache-Control:"no-cache, private"
, même si elle a été fournie parX-Requested-With:"XMLHttpRequest"
.Espérons que cela pourrait être utile à quelqu'un.
Ce qui se passait pour moi parce que j'avais mis de la taille de la mémoire cache trop petit (via la Stratégie de Groupe).
Il n'est pas arrivé dans Incognito, qui est ce qui m'a fait réaliser ce qui pourrait être le cas.
De fixation qui a résolu le problème.