Qu'est-ce que Cache-Control: private?

148

Lorsque je visite chesseng.herokuapp.com, j'obtiens un en-tête de réponse qui ressemble à

Cache-Control:private
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/css
Date:Tue, 16 Oct 2012 06:37:53 GMT
Last-Modified:Tue, 16 Oct 2012 03:13:38 GMT
Status:200 OK
transfer-encoding:chunked
Vary:Accept-Encoding
X-Rack-Cache:miss

puis je rafraîchis la page et j'obtiens

Cache-Control:private
Connection:keep-alive
Date:Tue, 16 Oct 2012 06:20:49 GMT
Status:304 Not Modified
X-Rack-Cache:miss

il semble donc que la mise en cache fonctionne. Si cela fonctionne pour la mise en cache, quel est l'intérêt de Expires et Cache-Control: max-age . Pour ajouter à la confusion, lorsque je teste la page à l' adresse https://developers.google.com/speed/pagespeed/insights/, il me dit de "tirer parti de la mise en cache du navigateur".

user782220
la source
Consultez ce diagramme stackoverflow.com/a/49925190/3748498
pravdomil

Réponses:

74

Pour répondre à votre question sur les raisons pour lesquelles la mise en cache fonctionne, même si le serveur Web n'a pas inclus les en-têtes:

  • Expire le: [a date]
  • Contrôle du cache: max-age =[seconds]

Le serveur a gentiment demandé à tous les mandataires intermédiaires de ne pas mettre en cache le contenu (c'est-à-dire que l'élément ne doit être mis en cache que dans un cache privé , c'est-à-dire uniquement sur votre propre machine locale):

  • Cache-Control: privé

Mais le serveur a oublié d'inclure toute sorte d'indices de mise en cache:

  • ils ont oublié d'inclure Expires , donc le navigateur sait utiliser la copie mise en cache jusqu'à cette date
  • ils ont oublié d'inclure Max-Age , donc le navigateur sait combien de temps l'élément mis en cache est valable
  • ils ont oublié d'inclure E-Tag , le navigateur peut donc faire une demande conditionnelle

Mais ils ont inclus une date de dernière modification dans la réponse:

Last-Modified: Tue, 16 Oct 2012 03:13:38 GMT

Étant donné que le navigateur connaît la date à laquelle le fichier a été modifié, il peut effectuer une demande conditionnelle . Il demandera le fichier au serveur, mais demandera au serveur de n'envoyer le fichier que s'il a été modifié depuis le 16/10/2012 3:13:38:

GET / HTTP/1.1
If-Modified-Since: Tue, 16 Oct 2012 03:13:38 GMT

Le serveur reçoit la demande, se rend compte que le client dispose déjà de la version la plus récente. Plutôt que d'envoyer le client 200 OK, suivi du contenu de la page, il vous indique plutôt que votre version en cache est bonne:

304 Not Modified

Votre navigateur a dû subir le délai d'envoi d'une demande au serveur et attendre une réponse, mais cela vous a évité d'avoir à télécharger à nouveau le contenu statique.

Pourquoi Max-Age ? Pourquoi expire ?

Parce que Last-Modified est nul.

Tout sur le serveur n'a pas une date associée. Si je construis une page à la volée, aucune date n'y est associée - c'est maintenant . Mais je suis parfaitement disposé à laisser l'utilisateur mettre en cache la page d'accueil pendant 15 secondes:

200 OK
Cache-Control: max-age=15

Si l'utilisateur martèle F5, il continuera à obtenir la version mise en cache pendant 15 secondes. S'il s'agit d'un proxy d'entreprise, tous les 67198 utilisateurs qui accèdent à la même page dans la même fenêtre de 15 secondes recevront tous le même contenu, tous servis à partir d'un cache fermé. La performance gagne pour tout le monde.

L'avantage de l'ajout Cache-Control: max-ageest que le navigateur n'a même pas à effectuer de requête conditionnelle .

  • si vous avez spécifié uniquement Last-Modified, le navigateur doit effectuer une requête If-Modified-Sinceet surveiller une 304 Not Modifiedréponse
  • si vous l'avez spécifié max-age, le navigateur n'aura même pas à subir l'aller-retour du réseau; le contenu sortira directement des caches

La différence entre "Cache-Control: max-age" et "Expires"

Expiresest un ancien équivalent de l'en- Cache-Control: max-agetête moderne (vers 1998) :

  • Expires: vous spécifiez une date (beurk)
  • max-age: vous spécifiez les secondes (bonté)
  • Et si les deux sont spécifiés, le navigateur utilise max-age:

    200 OK
    Cache-Control: max-age=60
    Expires: 20180403T192837 
    

Tout site Web écrit après 1998 ne devrait plus utiliser Expireset utiliser à la place max-age.

Qu'est-ce que ETag?

ETag est similaire à Last-Modified , sauf qu'il n'est pas nécessaire que ce soit une date - il faut juste que ce soit quelque chose .

Si je tire une liste de produits d'une base de données, le serveur peut envoyer le dernier rowversionsous forme d'ETag, plutôt que de date:

200 OK
ETag: "247986"

Mon ETag peut être le hachage SHA1 d'une ressource statique (par exemple, image, js, css, police), ou de la page rendue en cache (c'est-à-dire ce que fait le wiki Mozilla MDN; ils hachent le balisage final):

200 OK
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

Et exactement comme dans le cas d'une requête conditionnelle basée sur Last-Modified :

GET / HTTP/1.1
If-Modified-Since: Tue, 16 Oct 2012 03:13:38 GMT

304 Not Modified

Je peux effectuer une demande conditionnelle basée sur l'ETag:

GET / HTTP/1.1
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

304 Not Modified

An ETagest supérieur à Last-Modifiedparce qu'il fonctionne pour des choses autres que des fichiers ou des choses qui ont une notion de date . Juste est

Ian Boyd
la source
1
Impressionnant! J'ai placé une prime pour cette réponse. Que se passe-t-il s'il cache-controln'existe pas? Et vous n'avez que Etag? N'a-t-il pas encore besoin de faire une «requête conditionnelle» contre le serveur? Le comportement que je vois lorsque je suis hors ligne est qu'il revient juste du cache. Mais lorsqu'il est hors ligne, il ne peut pas faire cette demande conditionnelle. Cela signifie-t-il qu'il se mettra en cache indéfiniment si vous restez hors ligne? J'ai déjà posé cette question en détail ici . Pouvez-vous jeter un oeil?
Honey
168
Cache-Control: private

Indique que tout ou partie du message de réponse est destiné à un seul utilisateur et NE DOIT PAS être mis en cache par un cache partagé, tel qu'un serveur proxy.

De RFC2616 section 14.9.1

Dan D.
la source
14
Parce qu'il a été mis en cache par votre navigateur. Vous êtes le seul utilisateur auquel la réponse était destinée.
Dan D.
13
Non, ce n'est pas parce Cache-Control:privateque seuls les caches partagés (comme les caches proxy) ne doivent pas mettre en cache la réponse.
Dan D.
5
@Trejkaz Non, cela signifie vraiment un seul utilisateur. Un utilisateur est un compte qui possède son propre répertoire personnel dans lequel réside le cache. Les profils appartenant au même utilisateur peuvent partager leur cache. Comme vous l'avez trouvé. Mais deux profils sur le même ordinateur, s'ils appartiennent à des utilisateurs différents, ne doivent pas partager leur cache, sauf si ce cache est traité comme un cache partagé.
Dan D.
2
Ah, donc c'est par utilisateur au niveau du système d'exploitation. Oui, la raison pour laquelle je me pose la question est à cause d'une fuite d'informations apparente entre les fenêtres de navigation privée de Chrome et celles qui ne le sont pas, qui utilisent le cache pour le faire.
Trejkaz
2
@didibus proxy-revalidateexige que les proxys se revalident toujours à chaque accès. Où as privateempêche le proxy de se mettre en cache.
Dan D.
21

RFC 2616, section 14.9.1 :

Indique que tout ou partie du message de réponse est destiné à un seul utilisateur et NE DOIT PAS être mis en cache par une antémémoire partagée ... Une antémémoire privée (non partagée) PEUT mettre en cache la réponse.


Les navigateurs pourraient utiliser ces informations. Bien sûr, «l'utilisateur» actuel peut signifier plusieurs choses: utilisateur du système d'exploitation, utilisateur du navigateur (par exemple les profils de Chrome), etc. Ce n'est pas spécifié.

Pour moi, un exemple plus concret de Cache-Control: privatec'est que les serveurs proxy (qui ont généralement de nombreux utilisateurs) ne seront pas en cache. Il est destiné à l'utilisateur final, et à personne d'autre.


Pour info, la RFC précise que cela ne fournit pas de sécurité. Il s'agit de montrer le contenu correct, pas de sécuriser le contenu.

Cette utilisation du mot privé ne contrôle que l'endroit où la réponse peut être mise en cache et ne peut pas garantir la confidentialité du contenu du message.

Paul Draper
la source
5
Une antémémoire privée (non partagée) PEUT mettre en cache la réponse. Cette partie est essentielle. Merci.
Oliver
0

Le champ d'en-tête d'entité Expires donne la date / heure après laquelle la réponse est considérée comme obsolète. Le champ Cache-control: maxage donne la valeur d'âge (en secondes) plus grande que la réponse considérée comme obsolète.

Bien que le champ d'en-tête ci-dessus donne un mécanisme au client pour décider s'il doit envoyer une demande au serveur. Dans certaines conditions, le client envoie une demande au serveur et la valeur d'âge de la réponse est plus grande que la valeur maximale, la dose signifie-t-elle que le serveur doit envoyer la ressource au client? Peut-être que la ressource n'a jamais changé.

Afin de résoudre ce problème, HTTP1.1 donne la dernière tête modifiée. Le serveur donne la dernière date de modification de la réponse au client. Lorsque le client a besoin de cette ressource, il enverra le champ principal If-Modified-Since au serveur. Si cette date est antérieure à la date de modification de la ressource, le serveur enverra la ressource au client et donnera 200 codes. Sinon, il retournera 304 code au client et cela signifie que le client peut utiliser la ressource qu'il a mise en cache.

Lin.Yang
la source