У меня странная проблема с IIS 7.
Иногда кажется, что возвращается 304 вместо 200.
Вот пример запроса, захваченного с помощью Fiddler:
(Обратите внимание, что запрошенный файл еще не находится в кэше моего браузера.)
GET https://[mysite]/Content/js/jquery.form.js HTTP/1.1 Accept: */* Referer: https://[mysite]/Welcome/News Accept-Language: sv-SE User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; .NET4.0C; .NET4.0E) Accept-Encoding: gzip, deflate Host: [mysite] Connection: Keep-Alive Cache-Control: no-cache Cookie: ...
Обратите внимание, что в запросе нет If-Modified-Since или If-None-Match.
Но все же ответ:
HTTP/1.1 304 Not Modified Cache-Control: public Expires: Tue, 02 Mar 2010 06:26:08 GMT Last-Modified: Mon, 22 Feb 2010 21:58:44 GMT ETag: "1CAB40A337D4200" Server: Microsoft-IIS/7.5 X-Powered-By: ASP.NET Date: Mon, 01 Mar 2010 17:06:34 GMT
Кто-нибудь знает, что здесь может быть не так?
Я использую IIS 7 на Windows Web Server 2008 R2.
РЕДАКТИРОВАТЬ:
Я нашел обходной путь, включил кэширование, а затем отключил его на уровне расширения.
<configuration>
<system.webServer>
<caching enabled="true" enableKernelCache="true">
<profiles>
<add extension=".png" policy="DisableCache" kernelCachePolicy="DisableCache" />
<add extension=".gif" policy="DisableCache" kernelCachePolicy="DisableCache" />
<add extension=".js" policy="DisableCache" kernelCachePolicy="DisableCache" />
<add extension=".css" policy="DisableCache" kernelCachePolicy="DisableCache" />
</profiles>
</caching>
<staticContent>
<clientCache cacheControlMode="NoControl" />
</staticContent>
</system.webServer>
</configuration>
windows-server-2008
iis-7
asp.net
Ола Херрдал
источник
источник
Ответы:
Согласно разделу 14.9 спецификации HTTP1.1 ,
no-cache
директива для заголовка Cache-Control может быть применена только сервером происхождения, что означает, что IIS игнорирует заголовок в вашем запросе.Раздел 14.9.1 определяет
public
,private
иno-cache
как директивы, ограничивающие то, что кешируется, что может быть наложено только сервером.Если вы не хотите, чтобы ваш файл .js кэшировался, вам нужно либо установить
no-cache
директиву в приложении (то есть код ASP.NET), либо вам нужно изменитьCache-Control
заголовок в запросе, чтобы использоватьno-store
директиву вместоno-cache
.РЕДАКТИРОВАТЬ: на
основе вашего комментария - да, я предположил, что вы не хотите, чтобы файл кэшировался. Таким образом, 304 может появиться из-за того, что файл находится в одном из внутренних кэшей IIS. Посмотрите на это:
источник
Некоторое время у меня была такая же проблема, и все кэширование отключено ... Однако в какой-то момент я установил модуль сжатия для IIS7, который по умолчанию включил сжатие статических файлов на моих существующих сайтах. Я отключил все сжатие для затронутых участков, и теперь они, кажется, работают нормально на ощупь .
источник
Мы также сталкивались с этой ошибкой, но мы использовали библиотеку управления активами (кассету). После тщательного изучения этой проблемы мы обнаружили, что основной причиной этой проблемы является сочетание ASP.NET, IIS и кассеты. Я не уверен, что это ваша проблема (использование
Headers
API, а неCache
API), но шаблон, кажется, тот же.Ошибка № 1
Кассета устанавливает
Vary: Accept-Encoding
заголовок как часть своего ответа на пакет, поскольку она может кодировать содержимое с помощью gzip / deflate:Однако кэш вывода ASP.NET всегда будет возвращать ответ, который был кэширован первым. Например, если первый запрос имеет,
Accept-Encoding: gzip
а Cassette возвращает сжатый контент, кэш вывода ASP.NET будет кэшировать URL какContent-Encoding: gzip
. Следующий запрос к тому же URL, но с другой приемлемой кодировкой (напримерAccept-Encoding: deflate
) вернет кешированный ответ сContent-Encoding: gzip
.Эта ошибка вызвана тем, что Cassette использует
HttpResponseBase.Cache
API для установки параметров кэша вывода (напримерCache-Control: public
), но используетHttpResponseBase.Headers
API для установкиVary: Accept-Encoding
заголовка. Проблема заключается в том, что ASP.NETOutputCacheModule
является не знают заголовки ответа; это работает только черезCache
API. То есть он ожидает, что разработчик будет использовать невидимо тесно связанный API, а не только стандартный HTTP.Ошибка № 2
При использовании IIS 7.5 (Windows Server 2008 R2) ошибка # 1 может вызвать отдельную проблему с ядром IIS и пользовательским кэшем. Например, после успешного кэширования пакета
Content-Encoding: gzip
его можно увидеть в кэше ядра IIS с помощьюnetsh http show cachestate
. Он показывает ответ с 200 кодами состояния и кодировкой содержимого «gzip». Если следующий запрос имеет другую приемлемую кодировку (напримерAccept-Encoding: deflate
) и вIf-None-Match
заголовок, соответствующий хэш свертка, в запросе на ядрах и пользовательский режим кэшей IIS будет считаться промахом . Таким образом, вызывая обработку запроса кассетой, которая возвращает 304:Однако, как только ядро и пользовательские режимы IIS обработают ответ, они увидят, что ответ для URL изменился, и кэш должен быть обновлен. Если кэш ядра IIS проверяется
netsh http show cachestate
снова, кэшированный ответ 200 заменяется ответом 304. Все последующие запросы к комплекту независимо от ответаAccept-Encoding
иIf-None-Match
будут возвращать ответ 304. Мы увидели разрушительные последствия этой ошибки, когда все пользователи получили 304 для нашего основного скрипта из-за случайного запроса, который был неожиданнымAccept-Encoding
иIf-None-Match
.Кажется, проблема в том, что кэши ядра и пользовательского режима IIS не могут меняться в зависимости от
Accept-Encoding
заголовка. Как доказательство этого, при использованииCache
API с обходным решением ниже кэши ядра IIS и пользовательского режима, похоже, всегда пропускаются (используется только кэш вывода ASP.NET). Это можно подтвердить, проверив, чтоnetsh http show cachestate
пусто с обходным путем ниже. ASP.NET взаимодействует с работником IIS напрямую, чтобы выборочно включать или отключать ядро IIS и кэши пользовательского режима для каждого запроса.Мы не смогли воспроизвести эту ошибку на более новых версиях IIS (например, IIS Express 10). Тем не менее, ошибка № 1 была все еще воспроизводимой.
Наше первоначальное исправление этой ошибки заключалось в том, чтобы отключить кэширование в ядре / пользовательском режиме IIS только для запросов на кассету, как это уже упоминалось. Таким образом, мы обнаружили ошибку №1 при развертывании дополнительного уровня кэширования перед нашими веб-серверами. Причина того, что хак строки запроса сработал, заключается в том, что он
OutputCacheModule
будет регистрировать пропадание кэша, еслиCache
API не использовался для изменения в зависимости отQueryString
и если запрос имеетQueryString
.Временное решение
Мы все равно планировали отойти от Кассеты, поэтому вместо того, чтобы поддерживать наш собственный форк Кассеты (или пытаться объединить PR), мы решили использовать HTTP-модуль для решения этой проблемы.
Я надеюсь, что это помогает кому-то 😄!
источник