Quand un navigateur ne demande PAS un fichier au serveur?
En d'autres termes, j'ai un fichier JavaScript en cours de service. Son en-tête de réponse HTTP a une ETag
, Cache-Control: public
et Expires: Tue, 19 Jan 2038 03:14:07 GMT
.
Le serveur renvoie un 304
après l’amorçage du cache du navigateur.
Ma question est la suivante: pourquoi le navigateur vérifie-t-il même auprès du serveur et obtient-il un 304
? Je ne veux pas que le navigateur demande s'il y a une nouvelle version. Il doit se charger directement à partir du cache du navigateur sans vérifier les modifications apportées par le serveur qui dessert le script.
Quelle combinaison d'en-têtes de réponse HTTP accomplit ceci?
Premièrement, la spécification HTTP pertinente est RFC 7234 . Si vous regardez les spécifications, vous remarquerez deux choses:
Deuxièmement, vous ne faites rien de mal de votre côté. Les navigateurs sont libres de mettre en cache les réponses et de les utiliser, en fonction des en-têtes que vous renvoyez. Le point clé se trouve dans Section 4 , où il est noté que l’une des conditions pour fournir une réponse en cache est que la réponse est soit:
frais (voir section 4.2), ou
autorisé à être servi éventé (voir section 4.2.4), ou
validé avec succès (voir section 4.3).
Puisque vous crachez un en-tête Expires
qui est loin dans le futur et que ce point dans le futur n’a pas encore été atteint, la réponse est "fraîche" et la revalidation n’est donc pas requise. Donc, vous faites tout ce que les spécifications suggèrent que vous devriez être sur votre fin. (Bien que l'utilisation de Cache-Control: max-age=foo
soit un moyen plus moderne de définir les heures d'expiration du cache que d'utiliser l'en-tête Expires:
.)
Donc, si vous voulez changer le comportement de mise en cache des navigateurs, vous n’avez pas de chance.
Cependant , les choses pourraient ne pas être aussi mauvaises que vous le pensez. Vous ne voyez probablement qu'une requête et 304 car vous actualisez la page de votre navigateur lors des tests. Les navigateurs traitent les ressources en cache différemment selon la façon dont la demande les concernant a été déclenchée.
J'ai exécuté un test simple dans lequel j'ai créé une page HTML contenant une balise <script>
pointant vers un fichier JS, une balise <img>
pointant vers une image et une balise <link>
pointant vers une feuille de style CSS. Tous ces fichiers ont été hébergés sur un serveur Apache configuré pour les desservir avec:
Cache-Control: max-age=172800
Naturellement, toutes les ressources ont été servies avec 200 codes lors du chargement de la première page. Par la suite, en testant dans Chrome ou Firefox installe avec les paramètres par défaut, j'ai observé que:
Cette page indique qu'Internet Explorer a le même comportement:
Internet Explorer doit vérifier si une entrée mise en cache est valide dans un certain nombre de situations:
- L'entrée en cache n'a pas de date d'expiration et le contenu est en cours d'accès pour la première fois dans une session de navigateur.
- L'entrée mise en cache a une date d'expiration mais elle a expiré
- L'utilisateur a demandé une mise à jour de page en cliquant sur le bouton Actualiser ou en appuyant sur F5.
En d'autres termes, vous ne verrez généralement ces demandes de revalidation que si l'utilisateur actualise explicitement la page. À moins d’exigences particulières quant à la manière dont vous voulez que le cache du navigateur se comporte, ce comportement semble parfaitement raisonnable.
Google et Mozilla ont tous deux de la documentation sur la mise en cache HTTP (je ne trouve rien d’équivalent sur MSDN ou sur le site Apple Developers), mais ni ne suggère l’existence d’un fournisseur quelconque. des en-têtes de mise en cache spécifiques pouvant être utilisés pour modifier les règles utilisées par le navigateur pour choisir le moment de la revalidation. Ce que vous voulez faire est tout simplement impossible.
Si vous avez vraiment besoin de plus de contrôle sur ce comportement, vous pouvez consulter cache d’application HTML5 ou lancer votre propre logique de mise en cache à l’aide du stockage local HTML5, comme le fait basket.js .
Expires:
ou Cache-Control: max-age=
devrait fonctionner. Avez-vous confirmé dans les journaux du serveur que le navigateur passe réellement des appels réseau? J'ai constaté que firebug, par exemple, produisait une sortie déroutante, ce qui suggère que vous effectuez des appels à distance lorsque vous atteignez le cache.
Si vous êtes dans mon bateau et qu'une application angulaire est déployée sur IIS, assurez-vous que votre configuration web est configurée pour réécrire correctement l'URL, comme suit:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpErrors errorMode="Detailed" />
<rewrite>
<rules>
<rule name="Angular Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/NameOfYourApp_UnderDefaultWebSite/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Notez spécifiquement la valeur de l'URL dans
<action type="Rewrite" url="/NameOfYourApp_UnderDefaultWebSite/" />