web-dev-qa-db-fra.com

Gestion du cache du navigateur dans les applications à page unique

J'essaie de comprendre comment gérer correctement le cache du navigateur Web pour les applications à page unique.

J'ai une conception assez typique: plusieurs fichiers HTML, JS et CSS implémentant le SPA, et un tas de données JSON consommées par le SPA. Des problèmes surviennent lorsque je souhaite pousser une mise à jour: je mets à jour la partie statique du site et le code qui génère le JSON en même temps, mais les navigateurs clients ont souvent la partie statique mise en cache, donc l'ancien code essaie de traiter les nouvelles données et peut (en fonction des modifications apportées) rencontrer des problèmes. (En particulier, IE semble plus agressif que Chrome ou Firefox à propos de l'utilisation de JS en cache sans revalidation.)

Quelle est la meilleure façon de gérer cela?

  1. Assurez-vous que mes modifications JSON sont rétrocompatibles et supposez que les caches du navigateur expireront dans un délai raisonnable.
  2. Incorporez une sorte de numéro de version dans le JS statique et le JSON, puis exécutez window.location.reload(true); s'ils ne correspondent pas.
  3. Déterminez la combinaison appropriée d'en-têtes (must-revalidate ou no-cache ou peu importe; sourcesvarie comment faire) pour garantir que les navigateurs revalident toujours toutes les ressources à chaque chargement, même si cela signifie quelques allers-retours supplémentaires pour charger le site.
  4. Micro-gérer mon contrôle de cache et expire les en-têtes afin que le contenu statique expire lorsque je veux pousser une mise à jour.
  5. Autre chose?
30
Josh Kelley

Vous avez besoin d'une solution de contournement du cache . Le rôle de la suppression du cache est le suivant:

  1. Renommez les ressources en un nom unique en fonction de leur contenu.
  2. Mettez à jour toutes les références à ces ressources.

Dans un projet basé sur Grunt, il est courant d'utiliser grunt-rev pour garantir que tous les fichiers qui doivent être actualisés reçoivent des noms uniques, en fonction de leur contenu.

Si vous vous assurez que vos fichiers JSON obtiennent des noms de fichiers contournant le cache avec leurs références dans votre Javascript, les clients chargeront toujours les fichiers JSON attendus par Javascript.

L'avantage de la dénomination de fichiers basée sur le hachage est que les fichiers qui n'ont pas été modifiés obtiendront les mêmes noms de fichiers après le contournement du cache, afin que les navigateurs puissent continuer à utiliser en toute sécurité le contenu mis en cache lorsqu'il n'a pas changé.

De toute évidence, c'est le genre de chose que vous souhaitez automatiser dans le cadre de la construction de la production de votre projet, vous n'avez donc pas à suivre manuellement la modification des noms de fichiers et des références.

14
Ted Percival

Vous pouvez utiliser if-modified-since + last-modified ou if-none-match + etag en-têtes avec les bons cache-control entête. (Il peut y avoir bogues du navigateur , mais rien que vous ne pouvez pas gérer dans les navigateurs récents.)

Si les fichiers sont statiques, je vous suggère d'utiliser if-modified-since, car cela peut se faire automatiquement avec un serveur HTTP bien configuré. Il devrait renvoyer 304 si le fichier n'est pas modifié depuis le dernier téléchargement.

Je ne pense pas que vos # 1 et # 2 fonctionneraient à long terme. Le # 3 ou # 4 peut fonctionner. Le # 3 est plus simple, mais vous ne devez apprendre à gérer ce problème qu'une seule fois. J'essaierais donc le # 4 si j'étais vous, mais la solution pourrait dépendre des navigateurs que vos clients utilisent ... Par exemple IE8 a des problèmes en mettant à jour le cache ajax, etc ...

5
inf3rno

Si vous pouvez inclure Java Filtre de servlet dans votre SPA, voici une solution de travail: CorrectBrowserCacheHandlerFilter.Java

Fondamentalement, lorsque votre navigateur demande les fichiers statiques, le serveur redirige toutes les demandes vers la même mais avec un paramètre de requête de hachage (?v=azErT par exemple) qui dépend du contenu du fichier statique cible.

Ce faisant, le navigateur ne mettra jamais en cache les fichiers statiques déclarés dans votre index.htmlpar exemple (car recevra toujours un 302 Moved Temporarily), mais ne mettra en cache que ceux avec la version de hachage (le serveur répondra 200 pour eux). Ainsi, le cache du navigateur sera utilisé efficacement pour ces fichiers statiques avec une version de hachage.

Avertissement: je suis l'auteur de CorrectBrowserCacheHandlerFilter.Java.

2
Anthony O.