108 votes

Forcer les navigateurs à obtenir les derniers fichiers js et css dans l'application asp.net

Certains navigateurs mettent en cache les fichiers js et css, ne les rafraîchissant pas à moins que vous ne les forcier à le faire. Quel est le moyen le plus simple ?

Je viens de mettre en œuvre cette solution qui semble fonctionner.

Déclarez une variable de version sur votre page

  public string version { get; set; }

Récupérez le numéro de version à partir de la clé web.config

 version = ConfigurationManager.AppSettings["versionNumber"];

Dans votre page aspx, appelez les scripts et feuilles de style comme ceci

Ainsi, si vous définissez la version = 1.1 au lieu de 1.0 dans votre web.config, votre navigateur téléchargera les derniers fichiers, ce qui vous permettra, à vous et à vos utilisateurs, d'éviter certaines frustrations.

Y a-t-il une autre solution plus efficace, ou cela pourrait-il causer des problèmes imprévus pour un site web ?

0 votes

Question intéressante, j'ai récemment eu le même problème, mais c'était seulement un problème pendant les tests de développement. Je n'y ai pas trop prêté attention car nous n'avons pas l'intention de modifier ces fichiers après le lancement. J'aimerais tout de même connaître une solution pour référence future!

0 votes

Le seul problème que je peux voir est que les modifications apportées au web.config entraîneront, en arrière-plan, un redémarrage de l'application : msdn.microsoft.com/en-us/library/aa478432.aspx

0 votes

Merci pour la question. Cela m'a aidé à résoudre un gros problème.

81voto

Adam Tegen Points 8563

J'ai résolu cela en ajoutant un horodatage de dernière modification en tant que paramètre de requête aux scripts.

J'ai fait cela avec une méthode d'extension, et en l'utilisant dans mes fichiers CSHTML. Remarque : cette implémentation met en cache l'horodatage pendant 1 minute pour ne pas solliciter autant le disque.

Voici la méthode d'extension :

public static class JavascriptExtension {
    public static MvcHtmlString IncludeVersionedJs(this HtmlHelper helper, string filename) {
        string version = GetVersion(helper, filename);
        return MvcHtmlString.Create("");
    }

    private static string GetVersion(this HtmlHelper helper, string filename)
    {
        var context = helper.ViewContext.RequestContext.HttpContext;

        if (context.Cache[filename] == null)
        {
            var physicalPath = context.Server.MapPath(filename);
            var version = $"?v={new System.IO.FileInfo(physicalPath).LastWriteTime.ToString("MMddHHmmss")}";
            context.Cache.Add(filename, version, null,
              DateTime.Now.AddMinutes(5), TimeSpan.Zero,
              CacheItemPriority.Normal, null);
            return version;
        }
        else
        {
            return context.Cache[filename] as string;
        }
    }
}

Et ensuite dans la page CSHTML :

 @Html.IncludeVersionedJs("/MonFichierJavascript.js")

Dans le HTML rendu, cela apparaît comme :

1 votes

C'est génial pour MVC, je me demande si le dernier cadre MVC 5 gère ce problème? L'approche que la mise en paquet utilise avec le joker -{version} est également un moyen de résoudre ce problème, cependant cela nécessite que les fichiers soient renommés après chaque nouvelle construction...

0 votes

Je utilise les bases de votre exemple MVC dans un site web en webforms, et ça fonctionne très bien, alors merci de le partager!

0 votes

Devrait-il y avoir une raison de s'inquiéter de l'affichage de la date et de l'heure de la dernière modification des fichiers de ressources? Si un fichier utilisé avait une date et une heure de modification datant de quelques années, il pourrait s'agir d'une information que l'entreprise ne souhaite pas rendre publique à ses utilisateurs?

28voto

Daniel Vassallo Points 142049

Votre solution fonctionne. En fait, elle est assez populaire.

Même Stack Overflow utilise une méthode similaire :

v=6184 est probablement le numéro de révision SVN.

0 votes

Il s'agirait d'une approche beaucoup plus contraignante que celle décrite dans la réponse acceptée. Vérifier la version SVN du fichier à chaque fois qu'une page est servie représente un surcoût en termes de performances, en particulier à mesure que le nombre d'utilisateurs augmente avec le temps.

4 votes

Vous pouvez obtenir le numéro de révision lors de la construction, l'écrire dans un fichier (par exemple un fichier .cs partiel), inclure ce fichier dans votre projet, de sorte que vous n'ayez pas besoin de le lire depuis svn au moment de l'exécution. J'ai utilisé cette approche avec msbuild pour mettre les numéros de révision dans mes fichiers AssemblyInfo.cs à partir de svn.

2 votes

En utilisant un numéro de version / révision global a au moins un inconvénient : la publication d'une mise à jour du site Web invalide les caches des navigateurs pour tous les fichiers .js et .css, et pas seulement ceux qui ont été modifiés. Cela n'a probablement pas d'importance dans la plupart des applications, mais je le mentionne pour être complet.

7voto

JackArbiter Points 1892

Il y a une réponse plus simple à cela que la réponse donnée par l'auteur du livre dans la question (l'approche est la même) :

Définissez la clé dans le web.config :

Faites l'appel à appsettings directement depuis la page aspx :

" rel="stylesheet" type="text/css" />

0 votes

J'aime ça, mais je suis préoccupé de voir pourquoi cette solution a si peu de votes positifs...

0 votes

@SimplyInk Je ne sais pas, mais il y a 20 réponses différentes, donc cela pourrait avoir quelque chose à voir avec cela. Si cela fonctionne et que vous l'aimez, n'hésitez pas à lui donner un vote positif.

4voto

Pekka 웃 Points 249607

Curieusement, ce site même rencontre des problèmes avec l'approche que vous décrivez en ce qui concerne certaines configurations de proxy, même si elle devrait être infaillible.

Consultez cette discussion Meta Stack Overflow.

Par conséquent, il pourrait être judicieux de ne pas utiliser un paramètre GET pour mettre à jour, mais le nom réel du fichier :

href="http://stackoverflow.com/css/nomduscript/numérodeversion.css" 

même si cela demande plus de travail, car vous devrez réellement créer le fichier ou mettre en place une réécriture d'URL à cet effet.

0voto

Tim S. Van Haren Points 5936

Le principal problème de le faire de cette manière est principalement que vous devrez vous souvenir de mettre à jour votre numéro de version dans votre code chaque fois que vous apportez des modifications à vos fichiers css ou js.

Une manière peut-être meilleure de le faire est de définir un paramètre unique garanti avec chacun de vos fichiers css ou js, comme ceci :

Cela force les fichiers à être demandés au serveur à chaque fois, ce qui signifie également que votre site ne sera pas aussi performant lors du chargement de la page, car ces fichiers ne seront jamais mis en cache et utiliseront de la bande passante inutile à chaque fois.

Fondamentalement, si vous pouvez vous rappeler de mettre à jour le numéro de version à chaque modification, vous pouvez vous en sortir avec la façon dont vous le faites.

9 votes

Et utilise également des quantités importantes de bande passante.

2 votes

Correct, vous ne voulez pas une nouvelle version du JS à chaque chargement de page... vous voulez juste que le navigateur cherche une nouvelle version chaque fois que vous avez réellement une version mise à jour.

0 votes

Ceci est tout à fait acceptable pour une solution temporaire sur un fichier css de 50 Ko pendant le développement. +1

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X