IIS 7 возвращается 304 вместо 200

В Vista/Сервере 2008 каждая сеть имеет свой собственный профиль, и необходимо будет включить Файловые службы и Службы печати (netbios сервисы) для каждой сети.

Для большего количества справки попробуйте эти две ссылки: Включите Совместное использование Файла и Совместного использования и Печати Файла и Принтера в Vista

hth, ~H

10
задан 4 June 2010 в 16:08
3 ответа

Согласно разделу 14.9 из спецификации HTTP1.1, no-cache директива для заголовка Управления Кэша только imposable сервером источника, что означает, что IIS игнорирует заголовок в Вашем запросе.

Директивы управления кэша могут быть разломаны на эти общие категории:

  - Restrictions on what are cacheable; these may only be imposed

сервером источника.

Раздел 14.9.1 определяет public, private, и no-cache как направляющее ограничение, что является кэшируемым, который может только быть наложен сервером.

Если Вы не захотите, чтобы Ваш .js файл кэшировался, то необходимо будет или установить no-cache директива в приложении (т.е. - код ASP.NET) или необходимо будет измениться Cache-Control заголовок в запросе для использования no-store директива вместо no-cache.

Править:
На основе Вашего комментария - да я предположил, что Вы не хотели кэшируемый файл. Эти 304, затем, могли бы прибывать в результате файла, находящегося в одном из внутренних кэшей IIS. Взгляните на них:

3
ответ дан 2 December 2019 в 22:14
  • 1
    Я думаю, что Вы неправильно поняли мою проблему здесь. Файл еще не расположен в моем кэше. Но тем не менее сервер отвечает с 304... Это, кажется, происходит случайным образом при просматривании сайта во всех главных браузерах. –  Ola Herrdahl 1 March 2010 в 20:45
  • 2
    @Ola Herrdahl: Взгляните на мое редактирование. –  squillman 1 March 2010 в 21:15
  • 3
    Я попытался отключить кэширование в IIS также, и это не имеет никакого значения... :( –  Ola Herrdahl 2 March 2010 в 10:21

Я имел ту же проблему некоторое время и имею все выключенное кэширование... Однако я установил модуль Сжатия для IIS7 в какой-то момент, который по умолчанию включил сжатие статических файлов на моих существующих сайтах. Я выключил все сжатие для затронутых сайтов, и теперь они, кажется, хорошо работают сенсорная древесина.

1
ответ дан 2 December 2019 в 22:14

У нас тоже была эта ошибка, но мы использовали библиотеку управления активами (Cassette). После тщательного расследования этой проблемы мы обнаружили, что основная причина этой проблемы связана с комбинацией ASP.NET, IIS и Cassette. Я не уверен, что это ваша проблема (с использованием API Headers , а не Cache API), но картина, похоже, такая же.

Ошибка №1

Cassette устанавливает заголовок 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, использующим API HttpResponseBase.Cache для установки параметров кэша вывода (например, Cache-Control: public ), но с использованием API HttpResponseBase.Headers для установите заголовок Vary: Accept-Encoding . Проблема в том, что ASP.NET OutputCacheModule не знает заголовки ответа; он работает только через API Cache . То есть, он ожидает, что разработчик будет использовать невидимо тесно связанный 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 и пользовательский режим будет рассмотрен промах . Таким образом, вызывая обработку запроса с помощью Cassette, которая возвращает 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 . Доказательством этого является использование API Cache с обходным путем, описанным ниже, кэши ядра IIS и пользовательского режима кажутся всегда пропускаемыми (используется только кэш вывода ASP.NET). Это можно подтвердить, проверив, что netsh http show cachestate пусто, с помощью описанного ниже обходного пути. ASP.NET напрямую связывается с рабочим IIS, чтобы выборочно включать или отключать кеши ядра и пользовательского режима IIS для каждого запроса.

Нам не удалось воспроизвести эту ошибку в более новых версиях IIS (например, IIS Express 10). Однако ошибка №1 все еще воспроизводилась.

Нашим исходным исправлением этой ошибки было отключение кэширования в режиме ядра / пользователя IIS только для запросов кассеты, подобных другим, упомянутым. Таким образом, мы обнаружили ошибку №1 при развертывании дополнительного уровня кэширования перед нашими веб-серверами. Причина, по которой взлом строки запроса сработал, заключается в том, что OutputCacheModule будет записывать промах кеша, если API Cache не использовался для изменения на основе QueryString и , если запрос содержит QueryString .

Обходной путь

В любом случае мы планировали отказаться от Cassette, поэтому вместо того, чтобы поддерживать нашу собственную вилку Cassette (или пытаясь объединить PR), мы решили использовать HTTP-модуль, чтобы обойти эту проблему.

public class FixCassetteContentEncodingOutputCacheBugModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.PostRequestHandlerExecute += Context_PostRequestHandlerExecute;
    }

    private void Context_PostRequestHandlerExecute(object sender, EventArgs e)
    {
        var httpContext = HttpContext.Current;

        if (httpContext == null)
        {
            return;
        }

        var request = httpContext.Request;
        var response = httpContext.Response;

        if (request.HttpMethod != "GET")
        {
            return;
        }

        var path = request.Path;

        if (!path.StartsWith("/cassette.axd", StringComparison.InvariantCultureIgnoreCase))
        {
            return;
        }

        if (response.Headers["Vary"] == "Accept-Encoding")
        {
            httpContext.Response.Cache.VaryByHeaders.SetHeaders(new[] { "Accept-Encoding" });
        }
    }

    public void Dispose()
    {

    }
}

Надеюсь, это кому-то поможет

1
ответ дан 2 December 2019 в 22:14

Теги

Похожие вопросы