HTTP et le cache local des navigateurs

Lorsqu’un navigateur effectue une requête au serveur web, il dit généralement (traduit du HTTP en français):

salut www.rds.ca, pourrais-tu me donner la ressource /new_images/small_STEPLARO.gif ?

Un serveur Web bien configuré répondra quelque chose de ce genre:

  1. OK, voici l’image
  2. tu peux conserver cette image en cache pendant 24 heures (Cache-Control: max-age=86400, public)
  3. je te donne aussi un hash du contenu de l’image pour que tu vérifies que mon image n’a vraiment pas changé (Etag: "89bfd6-56a-444cef52ba15b")
  4. le serveur pourrait aussi répondre « Expires: Tue, 01 Dec 2009 16:00:00 GMT » ce qui est redondant avec le Cache-Control, mais puisque tous les clients, notamment les plus anciens, ne comprennent pas toujours très bien l’en-tête Cache-Control, Expires en est une alternative utile.

Ainsi, le navigateur va récupérer l’image, mais aussi garder en cache local une copie, avec une date d’expiration dans 24 heures. Si quelques minutes plus tard le navigateur a de nouveau besoin de cette image, il a le choix entre deux solutions:

  1. utiliser son cache local. Le navigateur peut le faire car le serveur lui a dit de conserver un cache.
  2. demander au serveur si l’image a changé depuis la dernière fois. Le client va envoyer une requête HTTP vérifiant la fraîcheur de son image en cache:
    GET http://www.rds.ca/new_images/small_STEPLARO.gif HTTP/1.1
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    If-Modified-Since: Mon, 28 Jan 2008 21:26:14 GMT
    If-None-Match: "89bfd6-56a-444cef52ba15b"
    Cache-Control: max-age=0
    

Dans ce cas, le serveur peut vérifier qu’effectivement, l’image n’a pas changé et n’aura pas besoin de renvoyer l’image, il lui suffit de répondre avec le statut HTTP 304 Not Modified.

Dans la plupart des cas, le second scenario est désirable: le client (navigateur) s’assure vraiment que la ressource est fraîche, et il n’y a presque pas de gâchis de bande passante. Par contre, dans les rares cas tels que rds.ca, ou le trafic et la charge des serveurs est immense, il nous serait très intéressant de ne pas avoir à gérer des millions de requêtes 304 Not Modified pour des images qui ont été correctement cachées! Malheureusement, nos recherches jusqu’ici s’avères infructueuses et il ne semble pas exister de directive de cache en HTTP qui forcerait l’utilisation (sans validation) de ressource cachée en local. Recherche à suivre…

Pour plus d’infos sur HTTP et la gestion des caches, la meilleure ressource (en Anglais) nous vient de Mark Nottingham: Caching Tutorial for Web Authors and Webmasters.

One comment

  1. Normalement, un client HTTP n’a besoin d’envoyer une requête If-Modified-Since (ou If-None-Match) que si le paramètre “no-cache” est spécifié dans l’entête Cache-Control.

    (évidemment, il ne leur est pas interdit de le faire ; mais je serais surpris que la plupart ne le fasse pas correctement)

    Note qu’il peut y avoir des interactions avec d’autres aspects d’HTTP, par exemple la négotiation de contenu : IE ne cache pas les ressources en conneg, je crois.

Leave a comment