Почему мой клиент отправляется на сервер, чтобы проверить, изменен ли файл при использовании пакетов ASP.NET MVC?

Я использую такой код:

bundles.Add(new ScriptBundle("~/bundles/textview")
                    .Include(
                        "~/Scripts/printarea/jquery.PrintArea.js",
                        "~/Scripts/pagedown/Markdown.Converter.js",
                        "~/Scripts/pagedown/Markdown.Sanitizer.js",
                        "~/Scripts/pagedown/Markdown.Editor.js"
                    ));

Это создает файл с датой истечения кеша на один год вперед, и это то, что появляется в моем script HTML, когда я смотрю на источник:

<script src="/bundles/textview?v=cNvP0r6Jo6hsl2Sdzhw-o3kAK7t2JdcNWiG0iIg7Lys1"></script>

Итак, почему я в fiddler все еще вижу, что он идет на сервер, чтобы проверить, был ли файл изменен? Есть ли способ, которым может быть изменена процедура пакета, так что она не добавляет? V = и вместо этого просто добавляет GUID к имени файла, например, через дефис между?

Ответ 1

Строка запроса v имеет маркер значения, который является уникальным идентификатором, используемым для кэширования. Пока пакет не изменится, приложение ASP.NET запросит пакет, используя этот токен. Если какой-либо файл в пакете изменится, инфраструктура оптимизации ASP.NET создаст новый токен, гарантирующий, что запросы браузера для пакета получат последний пакет.

Почему сервер проверяет?

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

Браузер будет обслуживать кешированные файлы, не проверяя их с сервером, если только одно из следующих значений:

  • Эвристика свежести не выполняется (т.е. файл в кеше не считается свежим).
  • Вы изменили заголовок expires или другой заголовок кеширования.
  • У вас установлен браузер для отключения кэширования.
  • URL-адрес ресурса изменяется или отличается.

Добавление файла Web.config в папку Scripts:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <staticContent>
             <clientCache cacheControlMode="UseExpires" 
                          httpExpires="Thu, 01 Jan 2016 00:00:00 GMT" />
        </staticContent>
    </system.webServer>
</configuration>

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

Как и для пучков, заголовки явно устанавливаются внутри System.Web.Optimization.dll:

private static void SetHeaders(BundleResponse bundle, BundleContext context)
{
    if (context.HttpContext.Response != null)
    {
        if (bundle.ContentType != null)
        {
            context.HttpContext.Response.ContentType = bundle.ContentType;
        }
        if (!context.EnableInstrumentation && context.HttpContext.Response.Cache != null)
        {
            HttpCachePolicyBase cache = context.HttpContext.Response.Cache;
            cache.SetCacheability(bundle.Cacheability);
            cache.SetOmitVaryStar(true);
            cache.SetExpires(DateTime.Now.AddYears(1));
            cache.SetValidUntilExpires(true);
            cache.SetLastModified(DateTime.Now);
            cache.VaryByHeaders["User-Agent"] = true;
        }
    }
}

поэтому вам нужно проверить, что вы не нарушаете никаких правил, заставляющих браузер проверяться с сервером!

ссылки:


Update

Если ваша цель состоит в том, чтобы ваши сценарии всегда были выбраны как:

<script src="/Scripts/printarea/jquery.PrintArea.js"></script>
<script src="/Scripts/pagedown/Markdown.Converter.js"></script>
<script src="/Scripts/pagedown/Markdown.Sanitizer.js"></script>
<script src="/Scripts/pagedown/Markdown.Editor.js></script>

Вместо

<script src="/bundles/textview?v=cNvP0r6Jo6hsl2Sdzhw-o3kAK7t2JdcNWiG0iIg7Lys1"></script>

Затем добавьте следующее к методу RegisterBundles (отключив объединение и минимизацию):

BundleTable.EnableOptimizations = false;

Если EnableOptimizations true или атрибут отладки в Компиляция Элемент в файле Web.config имеет значение false, файлы не будет в комплекте или не уменьшена. Кроме того, версия .min файлы не будут использоваться, будут выбраны полные версии отладки. EnableOptimizations переопределяет атрибут отладки в компиляции Элемент в файле Web.config

Ответ 2

Вероятно, имеет отношение к переменной querystring, зависящей от кэша, которую MVC присоединяет к URL-адресу:

Не включать строку запроса в URL-адрес для статических ресурсов.

Большинство прокси-серверов, в частности Squid до версии 3.0, не кэшируют ресурсы с помощью "?" в URL-адресе, даже если в ответе присутствует общий заголовок Cache-control: public. Чтобы включить кэширование прокси для этих ресурсов, удалите строки запросов из ссылок на статические ресурсы и вместо этого запишите параметры в имена файлов. "

ref: https://developers.google.com/speed/docs/best-practices/caching

Ответ 3

Когда вы говорите "все еще видите, что он идет на сервер, чтобы проверить, был ли файл изменен", какой код возврата? IE всегда будет запрашивать элементы, которые он кэшировал, например, пакеты. Он включает заголовки ETAG и LAST-MODIFIED в запросе. IIS обычно отвечает с 304 не измененными и без содержимого. Firefox, с другой стороны, вообще не будет делать никаких запросов. Это то, как браузер обрабатывает кеширование.

v querystring - это просто убедиться, что мы запрашиваем правильный файл. Поскольку IE всегда будет делать запрос и получить обратно 304, IE действительно не беспокоит v-строка. Однако Firefox с его агрессивным кэшированием увидит немного другой URL-адрес и сделает запрос на файл. Если этого параметра не было, Firefox не захочет запрашивать новый файл при изменении пакета.

Я не уверен, что делает Chrome, но подозреваю, что он ведет себя так же, как Firefox.