web-dev-qa-db-fra.com

Les réponses HTTP 304 non modifiées doivent-elles contenir des en-têtes de contrôle de cache?

J'ai essayé de comprendre cela et j'ai cherché SO pour des questions similaires, mais je n'ai toujours pas 100% de compréhension sur la façon dont cela est censé fonctionner.

J'obtiens cette réponse sur une demande de ressource image:

Response Headers
    Server  Apache-Coyote/1.1
    Date    Mon, 19 Oct 2009 09:04:04 GMT
    Expires Mon, 19 Oct 2009 09:06:05 GMT
    Cache-Control   public, max-age=120
    Etag    image_a70703fb393a60b6da346c112715a0abd54a3236
    Content-Disposition inline;filename="binary-216-420"
    Content-Type    image/jpg;charset=UTF-8
    Content-Length  4719

Le comportement souhaité est que le client doit le mettre en cache pendant 120 secondes, puis le demander à nouveau au serveur. Dans les 120 secondes, aucune demande n'est envoyée au serveur.

Puis, après 120 secondes, une demande est envoyée et une réponse 304 est reçue:

Response Headers
    Server  Apache-Coyote/1.1
    Date    Mon, 19 Oct 2009 09:06:13 GMT

Request Headers
    Host    localhost:8080
    User-Agent  Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3
    Accept  image/png,image/*;q=0.8,*/*;q=0.5
    Accept-Language en-us,no;q=0.8,sq;q=0.7,en;q=0.5,sv;q=0.3,nn;q=0.2
    Accept-Encoding gzip,deflate
    Accept-Charset  ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Keep-Alive  300
    Connection  keep-alive
    Referer http://localhost:8080/cms/site/0/en/home
    Cookie  JSESSIONID=768ABBE1A3BFABE3B535900233330650; versionsCssDisplayState=block; iceInfo=iceOn:false,activePortletKey:,icePagePanelX:1722,icePagePanelY:3
    If-None-Match   image_a70703fb393a60b6da346c112715a0abd54a3236

Jusqu'à présent, tout va bien. Mais alors, à la demande suivante (dans les 120 secondes), j'aurais pensé que la ressource devrait être mise en cache pendant 120 nouvelles secondes. Ce que je vois dans le navigateur (Firefox) d'autre part, c'est qu'à partir de ce moment, il demande toujours la ressource et reçoit la réponse 304.

Suis-je censé attacher les en-têtes de contrôle du cache dans la réponse 304? D'après ce que je peux lire dans la spécification, il semble que les paramètres de contrôle du cache devraient être omis et que le cache devrait le mettre en cache automatiquement pendant 120 nouvelles secondes?

55
runarM

En théorie, vous ne devriez pas avoir à envoyer Cache-Control pour un 304 - le destinataire devrait simplement continuer à utiliser les directives de cache qu'il a reçues du 200 d'origine. Cependant, comme vous l'avez trouvé, dans la pratique si vous ne le faites pas continuez à envoyer Cache-Control, les navigateurs ignoreront les directives de cache que vous avez envoyées à l'origine et reviendront à leurs propres heuristiques par défaut.

Donc, dans la pratique, vous devriez inclure le même Cache-Control avec un 304 que vous le feriez avec un 200. La spécification exige que vous l'envoyiez pour un 304 s'il est différent de ce que vous avez envoyé précédemment (voir 10.3.5 304 Non modifié ) - mais cela ne vous interdit certainement pas de le répéter quand c'est la même chose.

Et pour répondre spécifiquement aux points erronés de l'autre réponse (Structure):

  1. Vous voulez que les caches intermédiaires mettent en cache la réponse (c'est-à-dire, mettent à jour leur entrée de cache pour la ressource). Ils répondront de manière appropriée aux demandes des clients avec un 200 ou un 304, selon que le client a inclus un en-tête conditionnel comme If-Modified-Since.

  2. Le ttl de 120 secondes sera actualisé par le 304 (donc le même client ne devrait pas faire une autre demande pour la même ressource pendant au moins 120 secondes ). Et les clients, tant qu'ils ont toujours le contenu mis en cache, continueront à faire des demandes conditionnelles pour la ressource, auxquelles vous pourrez continuer de répondre avec un 304.

39
Justin Ludwig

RFC7232 met à jour RFC2616 pour dire:

Le serveur générant une réponse 304 DOIT générer l'un des champs d'en-tête suivants qui auraient été envoyés dans une réponse 200 (OK) à la même demande: Cache-Control, Content-Location, Date, ETag, Expires et Vary.

46
Mark Nottingham

Si je comprends bien, le navigateur met en cache pendant 120 secondes et votre serveur répond 304 Non modifié aux demandes If-Modified-Since ultérieures. Cette demande "IMS" se produit lorsque l'utilisateur final accède à la même URL. À ce moment, le navigateur peut envoyer une demande If-Modified-Since. Le navigateur veut savoir s'il affiche du contenu périmé. Cela semble normal.

Dès réception de cette demande, votre serveur doit répondre 200 OK, 304 Non modifié (ou un 4XX, si nécessaire).

Je ne pense pas que vous devez configurer votre serveur pour envoyer un en-tête Cache-Control avec la réponse 304 pour deux raisons:
1. Vous ne voulez pas de caches intermédiaires pour mettre en cache cette réponse 304 (il est possible qu'ils le puissent)
2. Les 120 secondes TTL ne seront pas actualisées par la réponse 304. Le navigateur conservera l'objet pendant 120 secondes à partir de la réponse 200 OK. Après 120 secondes, le navigateur devrait envoyer une demande GET, pas un If-Modified-Since, donc votre serveur répondra avec les octets du fichier et pas seulement une réponse 304.

Notez que le navigateur ne demandera pas à nouveau le fichier automatiquement après 120 secondes, sauf si l'utilisateur final le demande spécifiquement via un chargement de page ou en saisissant directement l'URL dans sa barre d'adresse (ou à moins que vous ayez une application personnalisée qui contrôle cette fonctionnalité d'une manière ou d'une autre).

Modification du premier paragraphe pour mieux lire (avec un peu de chance)

2
Structure