Как автоматически добавлять номера версий хэша md5 в файлы javascript и css в Visual Studio или использовать другой способ принудительного обновления кеша браузера?

Всякий раз, когда я выпускаю новую версию файлов CSS или javascript для любого из наших веб-приложений, я вручную добавляю ?v=# к URL-адресу в заголовке HTML (# — это номер версии, например 3 или 10), чтобы убедиться, что пользователи кеш браузера не мешает внесению изменений.

Но некоторые приложения имеют несколько файлов CSS и несколько файлов JS в голове, и утомительно отслеживать все измененные файлы.

Мы используем платформу ASP.NET на сервере IIS, поэтому, используя ответ на Какой элегантный способ заставить браузеры перезагружать кэшированные файлы CSS/JS? невозможно, но я ищу что-то подобное. Желательно все javascript.

Мне нравится предложение в этом посте использовать хэш md5, но я не могу найти способ вычислить контрольную сумму файла CSS или JS.

Код будет выглядеть примерно так (с использованием jQuery):

$.each($("script[type='text\javascript']"),function(){
    $(this).attr("src",$(this).attr("src") + "?v=" + checkMD5Sum($(this).attr("src")) );
});

function checkMD5Sum(url){
    //get the hash or something to auto version the file
    //I could send the url or filename to a webmethod to get the MD5 check sum, but doing this after page load is not usefull, so what to do?
}

Или, возможно, с помощью процесса пост-сборки в Visual Studio, но я никогда этого не делал, поэтому не хочу пробовать.


Изменить

Собираюсь попробовать это в web.config в соответствии с Добавление профилей кэширования

<configuration>
   <system.webServer>
      <caching enabled="true">
         <profiles>
            <add extension=".js" policy="CacheUntilChange" />
            <add extension=".css" policy="CacheUntilChange" />
         </profiles>
      </caching>
   </system.webServer>
</configuration>

person Daniël Tulp    schedule 14.09.2015    source источник


Ответы (2)


Похоже, ваше решение требует, чтобы браузер дважды извлекал файл, и вам не дается никаких гарантий состояния первого извлечения. Так что это не работает.

Кэшированием управляет сервер. Невозможно решить, когда новая версия будет доступна на клиенте, если только вы не проигнорируете кеш и всегда получите свежую копию.

Существует множество способов реализации политики кэширования. Одним из них является снятие отпечатков пальцев с номером версии.

Я предпочитаю использовать ETag. Пусть ETag будет временем файла, и все будет хорошо.

person Halcyon    schedule 14.09.2015
comment
Как мне реализовать ETag для файла в IIS? - person Daniël Tulp; 14.09.2015
comment
Я не знаю, как это работает в IIS, но в Apache вы можете настроить заголовок ETag в .htacess. Я ожидаю, что вы можете сделать что-то подобное для IIS. - person Halcyon; 14.09.2015
comment
вы можете сделать это в web.config, я полагаю, сделал это в другом проекте, но я не знаю, доступна ли опция filemtime - person Daniël Tulp; 14.09.2015
comment
technet.microsoft.com/en-us/ library/ee619764(v=ws.10).aspx Для всех версий IIS значение ETag для возвращаемого объекта основано на времени последнего изменения файла. - person Halcyon; 14.09.2015
comment
Я нахожусь на общем сервере, поэтому настроить IIS невозможно, но я, возможно, смогу использовать iis.net/configreference/system.webserver/caching/profiles/add, попробуем - person Daniël Tulp; 14.09.2015

  VersionNumber = System.Configuration.ConfigurationManager.AppSettings["Version"];

    //Caching Issues For JS
    public static string JSVersionUpdate(string JsFile)
    {
        StringBuilder str = new StringBuilder();
        str.Append(GetQualifiedPath(JsFile));
        str.Append("?Version=");
        str.Append(VersionNumber);
        return str.ToString();
    }

    public static void DiscardVersion()
    {
        VersionNumber = null;
    }

    //get Full Path for JS File
    private static string GetQualifiedPath(string path)
    {
        var httpRequestBase = new System.Web.HttpContextWrapper(System.Web.HttpContext.Current);

        path = path.Replace("~", string.Empty);

        string appPath = string.Empty;
        if (httpRequestBase != null)
        {
            //Formatting the fully qualified website url/name
            appPath = string.Format("{0}://{1}{2}{3}{4}",
                        httpRequestBase.Request.Url.Scheme,
                        httpRequestBase.Request.Url.Host,
                        httpRequestBase.Request.Url.Port == 80 ? string.Empty : ":" + httpRequestBase.Request.Url.Port,
                        httpRequestBase.Request.ApplicationPath,
                        path);
        }
        appPath = appPath.TrimEnd('/');

        return appPath;
    } 
}

На странице пользовательского интерфейса: script src="JSVersionUpdate("~/Scripts/Application/Abc.js")"

O/p : ~/Scripts/Application/Abc.js/version=1.0

Запрос браузера на файлы JS с сервера, только если версия отличается, иначе он будет кэширован. Теперь мне не нужно говорить кому-то, чтобы очистить кеш снова и снова после развертывания. Единственное, что я делаю, это меняю номер версии в веб-конфигурации.

person Pankaj    schedule 11.07.2017