web-dev-qa-db-fra.com

Qu'est-ce qui a la priorité: l'en-tête HTTP ETag ou Last-Modified?

Pour deux demandes ultérieures, lequel des deux en-têtes suivants reçoit plus de poids de la part des navigateurs si l'un d'eux change: ETag ou Last-Modified?

80
user101442

Selon RFC 2616 section 13.3.4, un client HTTP 1.1 DOIT utiliser l'ETag dans toutes les demandes conditionnelles de cache, et si un ETag et Last Modified sont présents, il DEVRAIT utiliser les deux. L'en-tête ETag est considéré comme un validateur puissant (voir la section 13.3.3), à moins qu'il ne soit explicitement déclaré faible par le serveur, tandis que l'en-tête Last Modified est considéré comme faible sauf s'il existe au moins une minute de différence entre lui et l'en-tête Date. Notez cependant que le serveur n'est pas obligé d'envoyer non plus (mais il DEVRAIT, s'il le peut).

Notez que le client ne vérifie pas les en-têtes pour voir s'ils ont changé; il les utilise simplement à l'aveugle dans la prochaine demande conditionnelle; il appartient au serveur d'évaluer s'il faut envoyer le contenu demandé ou une réponse 304 non modifiée. Si le serveur n'en envoie qu'un, le client l'utilisera seul (bien que seuls des validateurs solides soient utiles pour une demande de plage). Bien sûr, il est également à la discrétion des caches intermédiaires (à moins qu'ils n'aient pas été empêchés de mettre en cache via les directives de contrôle du cache) et du serveur quant à la façon dont ils agiront sur les en-têtes; le RFC déclare qu'ils NE DOIVENT PAS retourner un 304 non modifié si les validateurs sont incohérents, mais puisque les valeurs d'en-tête sont générées par le serveur, il a une certaine marge de manœuvre.

Dans la pratique, j'ai remarqué que Chrome, FireFox et IE 7+ envoient tous les deux en-têtes, si disponibles. J'ai également testé le comportement lors de l'envoi d'en-têtes modifiés, ce que j'avais déjà soupçonné d'après les informations dans le RFC. Les quatre clients que j'ai testés n'ont envoyé des demandes conditionnelles que si la ou les pages étaient actualisées ou si c'était la première fois que la page était demandée par le processus en cours.

89
Thomas S. Trias

N'est-ce pas plutôt une expression "OU". En pseudo code:

if ETagFromServer != ETagOnClient || LastModifiedFromServer != LastModifiedOnClient
   GetFromServer
else
   GetFromCache
20
Gidon

=! est l'opérateur de comparaison correct. Le client doit conserver la chaîne littérale reçue du serveur, car les conversions peuvent créer de petites différences. Vous ne pouvez pas supposer que "plus récent est meilleur".

Pourquoi? Prenons le cas où l'opérateur du serveur rétablit une mauvaise version d'une ressource. La version inversée est PLUS ANCIENNE - mais correcte.

Le client doit utiliser la version actuellement proposée par le serveur; il ne peut utiliser une version en cache que si elle est la même. Ainsi, le serveur doit vérifier l'égalité, pas "plus récent".

8
AccuracyInReponses