заставить браузеры получать последние файлы js и css в приложении asp.net

104

Некоторые браузеры кешируют файлы js и css, не обновляя их, если вы их не заставите. Самый простой способ.

Я только что реализовал это решение, которое, похоже, работает.

Объявите переменную версии на своей странице

  public string version { get; set; }

Получите номер версии из ключа web.config

 version = ConfigurationManager.AppSettings["versionNumber"];

На странице aspx выполняйте вызовы javascript и таблиц стилей, например

<script src="scripts/myjavascript.js?v=<%=version %>" type="text/javascript"></script>
<link href="styles/mystyle.css?v=<%=version %>" rel="stylesheet" type="text/css" />

Поэтому, если вы установите version = 1.1 из 1.0 в своем web.config, ваш браузер загрузит последние файлы, что, надеюсь, избавит вас и ваших пользователей от разочарования.

Есть ли другое решение, которое работает лучше, или это вызовет непредвиденные проблемы для веб-сайта?

киев
источник
Интересный вопрос, недавно у меня была такая же проблема, но она возникла только во время тестирования разработки. Не особо заботился об этом, так как мы не собираемся изменять этот файл после запуска. Хотел бы узнать решение для использования в будущем!
Бретт Аллен
Единственная проблема, которую я вижу, заключается в том, что изменения в web.config в фоновом режиме вызывают перезапуск приложения: msdn.microsoft.com/en-us/library/aa478432.aspx
monty
Спасибо за вопрос. Это помогло мне решить большую проблему.
Редди

Ответы:

76

Я решил эту проблему, добавив последнюю измененную временную метку в качестве параметра запроса к скриптам.

Я сделал это с помощью метода расширения и использовал его в своих файлах CSHTML. Примечание: эта реализация кэширует временную метку на 1 минуту, поэтому мы не так сильно загружаем диск.

Вот метод расширения:

public static class JavascriptExtension {
    public static MvcHtmlString IncludeVersionedJs(this HtmlHelper helper, string filename) {
        string version = GetVersion(helper, filename);
        return MvcHtmlString.Create("<script type='text/javascript' src='" + filename + version + "'></script>");
    }

    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;
        }
    }
}

А затем на странице CSHTML:

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

В обработанном HTML это выглядит так:

 <script type='text/javascript' src='/MyJavascriptFile.js?20111129120000'></script>
Адам Теген
источник
1
это отлично подходит для mvc, интересно, справится ли с этой проблемой последняя версия mvc 5? Подход, который используется при объединении с подстановочным знаком - {версия}, также является способом решения этой проблемы, однако он требует, чтобы файлы переименовывались после каждой новой сборки ...
Киев,
Я использую основы вашего примера MVC на веб-сайте веб-форм, и он отлично работает, так что спасибо за то, что поделились!
Брайан
Должны ли быть какие-либо причины для беспокойства по поводу отображения последней измененной отметки даты / времени для файлов ресурсов? Если используемый файл имеет отметку даты / времени несколько лет назад, может ли быть информация, которую компания может не захотеть публиковать для своих пользователей?
Брайан
Это стандартный способ, в основном следуют приложения. Но эта отметка времени должна измениться только при развертывании или создании приложения. В противном случае каждый раз, когда пользователь обновляет страницу или переключается на другие страницы в вашем приложении. Браузер снова загрузит все ваши таблицы стилей и javascript, что не очень хорошо
Тарун
2
Как это влияет на производительность страницы? Какую задержку может вызвать загрузка страницы?
Durgesh Sonawane
28

Ваше решение работает. На самом деле это довольно популярно.

Даже Stack Overflow использует похожий метод:

<link rel="stylesheet" href="http://sstatic.net/so/all.css?v=6184"> 

Где v=6184наверное номер ревизии SVN.

Даниэль Вассалло
источник
Это был бы гораздо более сложный подход, чем тот, который описан в принятом ответе. Проверка версии файла SVN каждый раз при обслуживании страницы снижает производительность, особенно если количество пользователей со временем увеличивается.
Neolisk
4
Вы можете получить номер версии во время сборки, записать его в файл (например, частичный файл .cs), включить этот файл в свой проект, чтобы вам не нужно было читать его из svn во время выполнения. Я использовал этот подход с msbuild, чтобы поместить номера ревизий в мои файлы AssemblyInfo.cs из svn.
Рамазан Бинарбаши
2
Использование глобального номера версии / ревизии имеет как минимум один недостаток: публикация обновления веб-сайта делает недействительными кеши браузера для всех файлов .js и .css, а не только для тех, которые изменились. В большинстве приложений это, наверное, не имеет значения, но я упоминаю об этом для полноты картины.
Адам
Если вы обновляете версию ваших файлов assemblyinfo.cs автоматически во время развертывания или сборки, для этого номера может использоваться дополнительная версия.
kristianp
28

В ASP.NET Core (MVC 6) это работает из коробки с помощью asp-append-versionпомощника тега:

<script src="scripts/myjavascript.js" asp-append-version="true"></script>
<link href="styles/mystyle.css rel="stylesheet" asp-append-version="true" />
metalheart
источник
1
Спасибо за то, что дали нам знать! Я не знал этого раньше!
Федерико Наваррете
18

ASP.NET MVC справится с этим за вас, если вы используете пакеты для своего JS / CSS. Он автоматически добавит номер версии в виде GUID к вашим пакетам и обновит этот GUID только при обновлении пакета (то есть в любом из исходных файлов есть изменения).

Это также помогает, если у вас много файлов JS / CSS, так как это может значительно сократить время загрузки контента!

Посмотреть здесь

оборота jonesy827
источник
Вы имеете в виду, что если мы используем пакеты в приложении MVC, нет необходимости в каких-либо методах в опубликованном здесь ответе? Если так, комплектация действительно намного важнее, чем я когда-либо думал. Не могли бы вы прояснить нам эту проблему? Спасибо.
Джек
1
Да, точно. Пока ваши скрипты включены в пакет, он автоматически генерирует номер версии для каждого пакета при обнаружении изменений в любом из исходных файлов пакета.
jonesy827
И не забывайте, что у вас как у разработчика все еще есть головные боли. Объединение ASP.NET никоим образом не помогает при отладке и разработке.
it3xl
12

Для этого в asp.net есть встроенный способ: объединение . Просто используйте это. Каждая новая версия будет иметь уникальный суффикс «? V = XXXXXXX». В режиме отладки связывание отключено, для включения настройки make в web.config:

<system.web>
    <compilation debug="false" />
</system.web>

Или добавьте в метод RegisterBundles (связки BundleCollection):

BundleTable.EnableOptimizations = true;

Например:

BundleConfig.cs:

bundles.Add(new ScriptBundle("~/Scripts/myjavascript.js")
                .Include("~/Scripts/myjavascript.js"));

bundles.Add(new StyleBundle("~/Content/mystyle.css")
                .Include("~/Content/mystyle.css"));

_Layout.cshtml:

@Scripts.Render("~/Scripts/myjavascript.js")
@Styles.Render("~/Content/mystyle.css")
Алексей Ткачук
источник
Но это будет работать только в среде выпуска или производства. Что насчет разработки при включенном режиме отладки? Пакет все еще решает эту проблему?
VAAA
Да, бандлэнд не облегчает жизнь разработчикам. Вы должны нажимать Ctrl-F5 после каждого изменения скрипта. А если будут кадры, будет еще веселее.
it3xl
7

На это есть более простой ответ, чем ответ, данный оператором в вопросе (подход тот же):

Определите ключ в web.config:

<add key="VersionNumber" value="06032014"/>

Сделайте вызов appsettings прямо со страницы aspx:

<link href="styles/navigation.css?v=<%=ConfigurationManager.AppSettings["VersionNumber"]%>" rel="stylesheet" type="text/css" />
оборота JackArbiter
источник
Мне это нравится, но меня беспокоит, почему у этого решения так мало голосов за ...
SimplyInk
@SimplyInk Я не знаю, но есть 20 разных ответов, так что это может иметь какое-то отношение. Если он работает и вам нравится, не стесняйтесь проголосовать за него.
JackArbiter
4

На основе ответа Адама Тегана , измененного для использования в приложении веб-форм.

В коде класса .cs:

public static class FileUtility
{
    public static string SetJsVersion(HttpContext context, string filename) {
        string version = GetJsFileVersion(context, filename);
        return filename + version;
    }

    private static string GetJsFileVersion(HttpContext context, string filename)
    {
        if (context.Cache[filename] == null)
        {
            string filePhysicalPath = context.Server.MapPath(filename);

            string version = "?v=" + GetFileLastModifiedDateTime(context, filePhysicalPath, "yyyyMMddhhmmss");

            return version;
        }
        else
        {
            return string.Empty;
        }
    }

    public static string GetFileLastModifiedDateTime(HttpContext context, string filePath, string dateFormat)
    {
        return new System.IO.FileInfo(filePath).LastWriteTime.ToString(dateFormat);
    }
}

В разметке aspx:

<script type="text/javascript" src='<%= FileUtility.SetJsVersion(Context,"/js/exampleJavaScriptFile.js") %>'></script>

А в обработанном HTML-коде он выглядит как

<script type="text/javascript" src='/js/exampleJavaScriptFile.js?v=20150402021544'></script>
Брайана
источник
2
Привет! Ваш пример работает, но вам следует либо удалить ссылки на кеширование, либо исправить код, чтобы использовать кеш, потому что это может сбивать с толку, почему вы его используете. Чтобы использовать кеш, вы должны добавить версию файла в кеш, используя метод context.Cache.Add в случае context.Cache [filename] == null. Если context.Cache [filename]! = Null, вы должны вернуть кешированное значение (context.Cache [filename])
Flavia Obreja
1
Флавия, я думаю, что ваше объяснение имеет смысл, и я думаю, что это более простая и эффективная реализация. Спасибо за полезные комментарии и отзывы.
Брайан
4

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

Проверьте это обсуждение Meta Stack Overflow .

Поэтому в свете этого может иметь смысл использовать для обновления не параметр GET, а фактическое имя файла:

href="/css/scriptname/versionNumber.css" 

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

Пекка 웃
источник
4

Мне нужен был простой лайнер, чтобы сделать путь уникальным для разрушения кеша. Это сработало для меня:

<script src="scripts/main.js?bust_js_cache=<%=System.IO.File.GetLastWriteTime(Server.MapPath("scripts/main.js")).ToString("HH:mm:ss")%>" type="text/javascript"></script>

Если файл был изменен с момента последней загрузки на страницу, браузер извлечет обновленный файл.

Он генерирует last modifiedштамп из .jsфайла и помещает его туда вместо версии, доступ к которой может быть нелегким.

<script src="scripts/main.js?bust_js_cache=10:18:38" type="text/javascript"></script>

Другой вариант - получить контрольную сумму файла.

снайпер
источник
1
Безусловно, это самый простой способ сделать это и, вероятно, с наименьшими накладными расходами.
Тони Хинкль
1
Идеальное решение. Я также протестировал Chrome 70, Firefox 63 и IE 11, чтобы убедиться, что кеширование действительно работает. Это. Это блокирует кеширование только новых версий файла, по крайней мере, в последних версиях браузеров. В другом месте я слышал упоминание о том, что некоторые браузеры перезагружают каждый файл с помощью строки запроса (?). Может быть, так было раньше, а может быть, это все еще верно для Safari и Opera. DK.
Брэд Мэтьюз,
3

Вот подход, который работает с ASP.NET 5 / MVC 6 / vNext .

Шаг 1. Создайте класс для возврата времени последней записи файла, как и в других ответах в этом потоке. Обратите внимание: для этого требуется внедрение зависимостей ASP.NET 5 (или другого).

public class FileVersionService
{
    private IHostingEnvironment _hostingEnvironment;
    public FileVersionService(IHostingEnvironment hostingEnvironment)
    {
        _hostingEnvironment = hostingEnvironment;
    }

    public string GetFileVersion(string filename)
    {
       var path = string.Format("{0}{1}", _hostingEnvironment.WebRootPath, filename);
       var fileInfo = new FileInfo(path);
       var version = fileInfo.LastWriteTimeUtc.ToString("yyyyMMddhhmmssfff");
       return version;
     }
}

Шаг 2: Зарегистрируйте сервис для внедрения в startup.cs :

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddScoped<FileVersionService>();
    ...
}

Шаг 3. Затем в ASP.NET 5 можно внедрить службу непосредственно в представление макета, например _Layout.cshtml, следующим образом:

@inject Namespace.Here.FileVersionService fileVersionService
<!DOCTYPE html>
<html lang="en" class="@ViewBag.HtmlClass">
<head>
    ...
    <link href="/css/styles.css?v=@fileVersionService.GetFileVersion("\\css\\styles.css")" rel="stylesheet" />
    ...
</head>
<body>
    ...
</body>

Есть некоторые последние штрихи, которые можно было бы сделать, чтобы лучше объединить физические пути и обработать имя файла в стиле, более совместимом с синтаксисом, но это отправная точка. Надеюсь, это поможет людям перейти на ASP.NET 5.

Ender2050
источник
такое поведение действительно поддерживается из коробки, см. мой ответ
metalheart
3

На моем сайте aspnet MVC 4 я использовал немного другую технику:

_ViewStart.cshtml:

@using System.Web.Caching
@using System.Web.Hosting
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
    PageData.Add("scriptFormat", string.Format("<script src=\"{{0}}?_={0}\"></script>", GetDeployTicks()));
}

@functions
{

    private static string GetDeployTicks()
    {
        const string cacheKey = "DeployTicks";
        var returnValue = HttpRuntime.Cache[cacheKey] as string;
        if (null == returnValue)
        {
            var absolute = HostingEnvironment.MapPath("~/Web.config");
            returnValue = File.GetLastWriteTime(absolute).Ticks.ToString();
            HttpRuntime.Cache.Insert(cacheKey, returnValue, new CacheDependency(absolute));
        }
        return returnValue;
    }
}

Затем в реальных представлениях:

 @Scripts.RenderFormat(PageData["scriptFormat"], "~/Scripts/Search/javascriptFile.min.js")
Энтони Вулф
источник
3

<?php $rand_no = rand(10000000, 99999999)?> <script src="scripts/myjavascript.js?v=<?=$rand_no"></script>

У меня это работает во всех браузерах. Здесь я использовал PHP для генерации случайного числа. Вы можете использовать свой собственный серверный язык.

Мукеш Рай
источник
Хороший ответ, но ASP MVC может быть немного проблематичным, если вы не учитываете то, что объяснил Адам, потому что я пробовал это, а папка Bundle не распознает его, если вы работаете с MVC 5. Но спасибо за предложение!
Федерико Наваррете,
2

Начиная с приведенного выше ответа, я немного изменил код, чтобы помощник работал и с файлами CSS, и добавлял версию каждый раз, когда вы вносите какие-то изменения в файлы, а не только при сборке.

public static class HtmlHelperExtensions
{
    public static MvcHtmlString IncludeVersionedJs(this HtmlHelper helper, string filename)
    {
        string version = GetVersion(helper, filename);
        return MvcHtmlString.Create("<script type='text/javascript' src='" + filename + version + "'></script>");
    }

    public static MvcHtmlString IncludeVersionedCss(this HtmlHelper helper, string filename)
    {
        string version = GetVersion(helper, filename);
        return MvcHtmlString.Create("<link href='" + filename + version + "' type ='text/css' rel='stylesheet'/>");
    }

    private static string GetVersion(this HtmlHelper helper, string filename)
    {
        var context = helper.ViewContext.RequestContext.HttpContext;
        var physicalPath = context.Server.MapPath(filename);
        var version = "?v=" +
        new System.IO.FileInfo(physicalPath).LastWriteTime
        .ToString("yyyyMMddHHmmss");
        context.Cache.Add(physicalPath, version, null,
          DateTime.Now.AddMinutes(1), TimeSpan.Zero,
          CacheItemPriority.Normal, null);

        if (context.Cache[filename] == null)
        {
            context.Cache[filename] = version;
            return version;
        }
        else
        {
            if (version != context.Cache[filename].ToString())
            {
                context.Cache[filename] = version;
                return version;
            }
            return context.Cache[filename] as string;
        }
    }
}
оборота Sergi Mulà
источник
1

Получите время изменения файла, как показано ниже

private static string GetLastWriteTimeForFile(string pathVal)
    {
        return System.IO.File.GetLastWriteTime(HostingEnvironment.MapPath(pathVal)).ToFileTime().ToString();
    }

Добавьте это с вводом как строку запроса

public static string AppendDateInFile(string pathVal)
    {
        var patheWithDate = new StringBuilder(pathVal);
        patheWithDate.AppendFormat("{0}x={1}",
                               pathVal.IndexOf('?') >= 0 ? '&' : '?',
                               GetLastWriteTimeForFile(pathVal));
        return patheWithDate.ToString();
    }

Вызовите это из разметки.

Подход помощника по расширению MVC

Добавить метод расширения

namespace TNS.Portal.Helpers
{
    public static class ScriptExtensions
    {
        public static HtmlString QueryStringScript<T>(this HtmlHelper<T> html, string path)
        {
            var file = html.ViewContext.HttpContext.Server.MapPath(path);
            DateTime lastModified = File.GetLastWriteTime(file);
            TagBuilder builder = new TagBuilder("script");
            builder.Attributes["src"] = path + "?modified=" + lastModified.ToString("yyyyMMddhhmmss");
            return new HtmlString(builder.ToString());
        }

       public static HtmlString QueryStringStylesheet<T>(this HtmlHelper<T> html, string path)
       {
        var file = html.ViewContext.HttpContext.Server.MapPath(path);
        DateTime lastModified = File.GetLastWriteTime(file);
        TagBuilder builder = new TagBuilder("link");
        builder.Attributes["href"] = path + "?modified=" + lastModified.ToString("yyyyMMddhhmmss");
        builder.Attributes["rel"] = "stylesheet";
        return new HtmlString(builder.ToString());
      }

    }
}

Добавьте это пространство имен в web.config

<system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Optimization"/>
        <add namespace="System.Web.Routing" />
        <add namespace="TNS.Portal" />
        <add namespace="TNS.Portal.Helpers" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>

Используйте его как

@Html.QueryStringScript("/Scripts/NPIAjaxCalls.js")
@Html.QueryStringStylesheet("/Content/StyledRadio.css")
оборота Lijo
источник
1

Упрощенные предыдущие предложения и предоставление кода для разработчиков .NET Web Forms.

Это будет принимать как относительные ("~ /"), так и абсолютные URL-адреса в пути к файлу ресурса.

Поместите в файл класса статических расширений следующее:

public static string VersionedContent(this HttpContext httpContext, string virtualFilePath)
{
    var physicalFilePath = httpContext.Server.MapPath(virtualFilePath);
    if (httpContext.Cache[physicalFilePath] == null)
    {
        httpContext.Cache[physicalFilePath] = ((Page)httpContext.CurrentHandler).ResolveUrl(virtualFilePath) + (virtualFilePath.Contains("?") ? "&" : "?") + "v=" + File.GetLastWriteTime(physicalFilePath).ToString("yyyyMMddHHmmss");
    }
    return (string)httpContext.Cache[physicalFilePath];
}

А затем назовите его на своей мастер-странице как таковой:

<link type="text/css" rel="stylesheet" href="<%= Context.VersionedContent("~/styles/mystyle.css") %>" />
<script type="text/javascript" src="<%= Context.VersionedContent("~/scripts/myjavascript.js") %>"></script>
Джейсон Эллингсон
источник
Тоже хороший подход!
Федерико Наваррете
0

Основываясь на приведенном выше ответе, я написал небольшой класс расширения для работы с файлами CSS и JS:

public static class TimestampedContentExtensions
{
    public static string VersionedContent(this UrlHelper helper, string contentPath)
    {
        var context = helper.RequestContext.HttpContext;

        if (context.Cache[contentPath] == null)
        {
            var physicalPath = context.Server.MapPath(contentPath);
            var version = @"v=" + new FileInfo(physicalPath).LastWriteTime.ToString(@"yyyyMMddHHmmss");

            var translatedContentPath = helper.Content(contentPath);

            var versionedContentPath =
                contentPath.Contains(@"?")
                    ? translatedContentPath + @"&" + version
                    : translatedContentPath + @"?" + version;

            context.Cache.Add(physicalPath, version, null, DateTime.Now.AddMinutes(1), TimeSpan.Zero,
                CacheItemPriority.Normal, null);

            context.Cache[contentPath] = versionedContentPath;
            return versionedContentPath;
        }
        else
        {
            return context.Cache[contentPath] as string;
        }
    }
}

Вместо того, чтобы писать что-то вроде:

<link href="@Url.Content(@"~/Content/bootstrap.min.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content(@"~/Scripts/bootstrap.min.js")"></script>

Теперь вы можете написать:

<link href="@Url.VersionedContent(@"~/Content/bootstrap.min.css")" rel="stylesheet" type="text/css" />
<script src="@Url.VersionedContent(@"~/Scripts/bootstrap.min.js")"></script>

Т.е. просто замените Url.Contentна Url.VersionedContent.

Сгенерированные URL-адреса выглядят примерно так:

<link href="/Content/bootstrap.min.css?v=20151104105858" rel="stylesheet" type="text/css" />
<script src="/Scripts/bootstrap.min.js?v=20151029213517"></script>

Если вы используете класс расширения, вы можете добавить обработку ошибок в случае, если MapPathвызов не работает, поскольку contentPathэто не физический файл.

Уве Кейм
источник
0

Я использую аналогичный способ сделать то же самое, что и вы, без изменения каждой страницы. Добавлено событие PreRender в мастер-файл. Он сохраняет мою логику в одном месте и применим как к файлам js, так и к файлам css.

protected void Page_PreRender(object sender, EventArgs e)
    {
        HtmlLink link = null;
        LiteralControl script = null;


        foreach (Control c in Header.Controls)
        {
            //StyleSheet add version
            if (c is HtmlLink)
            {
                link = c as HtmlLink;


                if (link.Href.EndsWith(".css", StringComparison.InvariantCultureIgnoreCase))
                {
                    link.Href += string.Format("?v={0}", ConfigurationManager.AppSettings["agVersion"]);
                }

            }

            //Js add version
            if (c is LiteralControl)
            {
                script = c as LiteralControl;

                if (script.Text.Contains(".js"))
                {
                    var foundIndexes = new List<int>();


                    for (int i = script.Text.IndexOf(".js\""); i > -1; i = script.Text.IndexOf(".js\"", i + 1))
                    {

                        foundIndexes.Add(i);
                    }

                    for (int i = foundIndexes.Count - 1; i >= 0; i--)
                    {

                        script.Text = script.Text.Insert(foundIndexes[i] + 3, string.Format("?v={0}", ConfigurationManager.AppSettings["agVersion"]));
                    }
                }

            }

        }
    }
Джей
источник
0

Вы можете переопределить свойство DefaultTagFormat скриптов или стилей.

Scripts.DefaultTagFormat = @"<script src=""{0}?v=" + ConfigurationManager.AppSettings["pubversion"] + @"""></script>";
Styles.DefaultTagFormat = @"<link href=""{0}?v=" + ConfigurationManager.AppSettings["pubversion"] + @""" rel=""stylesheet""/>";
Феникс
источник
0

Для решения этой проблемы в моем приложении ASP.Net Ajax я создал расширение, а затем вызвал его на главной странице.

Более подробно вы можете пройти по ссылке .

Касым Хусаини
источник
0

Простой и умный способ реализовать управление версиями css в приложении .net с помощью приведенной ниже концепции. Нет необходимости писать внутренний код.

<link href="<%="../../App_Themes/Base/css/main.css?v="+ DateTime.Now.ToString("yyyyMMddhhmmss") +""%>" rel="stylesheet" />
СантошК
источник
это приведет к принудительной загрузке при каждом рендеринге страницы, даже если файлы вообще не изменились.
Танасис Иоаннидис,
@ThanasisIoannidis Его можно использовать там, где файлы регулярно меняются. другой вариант - добавить ключ appVersion в web.config и использовать с именем файла .. но вам нужно обновить его, когда вы выпускаете приложение для prod.
SantoshK
-1

Основная проблема, связанная с этим способом, в основном состоит в том, что вам нужно не забывать обновлять номер версии в своем коде каждый раз, когда вы вносите какие-либо изменения в файлы css или js.

Возможно, лучший способ сделать это - установить гарантированный уникальный параметр для каждого из ваших файлов css или js, например:

<script src="scripts/myjavascript.js?_=<%=DateTime.Now.Ticks%>" type="text/javascript"></script>
<link href="styles/mystyle.css?_=<%=DateTime.Now.Ticks%>" rel="stylesheet" type="text/css" />

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

По сути, если вы не забываете обновлять номер версии каждый раз, когда вносятся изменения, вам может сойти с рук то, как вы это делаете.

Тим С. Ван Харен
источник
9
и также использует много пропускной способности.
Даррен Копп
2
Правильно, вам не нужна новая версия JS при каждой загрузке страницы ... вы просто хотите, чтобы браузер искал новую версию каждый раз, когда у вас действительно есть обновленная версия.
kingdango 03
Это вполне приемлемо для временного решения для файла css размером 50 КБ, находящегося в разработке. +1
Colbs
-2

Для страниц ASP.NET я использую следующие

ПЕРЕД

<script src="/Scripts/pages/common.js" type="text/javascript"></script>

ПОСЛЕ (принудительная перезагрузка)

 <script src="/Scripts/pages/common.js?ver<%=DateTime.Now.Ticks.ToString()%>" type="text/javascript"></script>

Добавление DateTime.Now.Ticks работает очень хорошо.

Рави Рам
источник
да, проблема связана с пропускной способностью - как в комментариях выше stackoverflow.com/a/2185918/59508
Киев,