Остановите IIS 7.5 от отправки Max-Age Cache-Control на коды ошибок

10

У меня есть статический контент с Max-Ageприкрепленными к нему заголовками управления кэшем, поэтому клиенты будут кэшировать статический контент. Тем не менее IIS 7.5 по-прежнему отправляет этот заголовок, когда есть сообщения об ошибках, рекомендующие клиенту кешировать это.

Это отрицательно сказывается на том, что некоторые прокси-серверы затем кэшируют этот ответ об ошибке. Я мог бы, Vary: Accept,Accept-Encodingно это на самом деле не решает основную проблему Max-Ageвыхода из ошибок.

Текущий соответствующий web.configраздел IIS :

<configuration>
  <system.webServer>
    <staticContent>
      <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
    </staticContent>
  </system.webServer>
</configuration>

Есть ли способ сделать так, чтобы мы не говорили клиентам или прокси кешировать коды ошибок 400/500?

Кайл Брандт
источник
Вы используете пользовательские страницы ошибок?
Джастин Нисснер,
@Justin - Нет, не в этом случае
Ник Крейвер
IIS 7.0 не отправляет Max-Age для 40 * для меня. Я не уверен, если это несоответствие между версиями IIS все же.
Дэвид Мердок
Кроме того, как заставить статический контент отправить код ошибки 500?
Дэвид Мердок
1
@DavidMurdoch, например, мы видим 406 ответов, отправленных с заголовками управления кэшем, когда пользователи запрашивают JavaScript, но клиент принимает только типы изображений MIME. Прокси-серверы соблюдают эту директиву кэширования (как и должно быть в спецификации), и другие пользователи не могут загрузить скрипт.
Джаррод Диксон

Ответы:

2

Я создал элементарный тестовый набор.

Когда я запускаю тесты с минимальным Web.config на IIS 7.0 (Интегрированный режим трубопровода в .NET 4.0), все проходит; Cache-Controlзаголовок ответа тестового файла устанавливается в том privateслучае, если его Acceptзаголовок запроса не совпадает с заголовком файла Content-Type.

Это наводит меня на мысль, что у вас есть какой-то модуль, прерывающий процедуру статического кэширования IIS, или IIS 7.0 и 7.5 отличаются здесь.

Вот файлы, которые я использовал (без some-script.jsтак как это просто пустой файл):

Web.Config:

<?xml version="1.0"?>
<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0">
        </compilation>
    </system.web>
    <system.webServer>
        <staticContent>
            <!-- Set expire headers to 30 days for static content-->
            <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
        </staticContent>
    </system.webServer>
</configuration>

test.html:

<!doctype html>
<html>
<head>
    <title>http://serverfault.com/questions/346975</title>
    <style>
        body > div
        {
            border:1px solid;
            padding:10px;
            margin:10px;
        }
    </style>
</head>
    <body>
        <div>
            <h2>Request JS file with Accepts: accept/nothing</h2>
            <b>Response Headers: </b>
            <pre id="responseHeaders-1">loading&hellip</pre>
        </div>

        <div>
            <h2>Request JS file with Accepts: */*</h2>
            <b>Response Headers: </b>
            <pre id="responseHeaders-2">loading&hellip</pre>
        </div>

        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
        <script>
            var responseHeaders1 = $("#responseHeaders-1"),
                responseHeaders2 = $("#responseHeaders-2"),
                fetchScript = function (accepts, element, successMsg, errorMsg) {

                    var jXhr = $.ajax({
                        // fetch the resource "fresh" each time since we are testing the Cache-Control header and not caching itself
                        "url": "some-script.js?" + (new Date).getTime(),
                        "headers": {
                            "Accept" : accepts
                        },
                        "complete": function () {
                            var headers = jXhr.getAllResponseHeaders();
                            headers = headers.replace(/(Cache-Control:.+)/i, "<strong><u>$1</u></strong>");
                            element.html(headers);
                        },
                        "success": function () {
                            element.after("<div>" + successMsg + "</div>");
                        },
                        "error": function () {
                            element.after("<div>" + errorMsg + "</div>");
                        }
                    });
                };

                fetchScript("accept/nothing", responseHeaders1, "Uh, your server is sending stuff when the client doesn't accept it.", "Your server (probably) responded correctly.");
                fetchScript("*/*", responseHeaders2, "Your server responded correctly.", "Something went wrong.");
        </script>
    </body>
</html>
Дэвид Мердок
источник
Мы можем воспроизвести ваши результаты с помощью запросов к localhost. Пробовали ли вы выполнять те же тесты с удаленной машины?
Джефф Далгас
Да. se.vervestudios.co/tests/se-test/test.html (обратите внимание на людей будущего, предыдущая ссылка была только для целей временного тестирования и, вероятно, больше не работает, извините)
Дэвид Мердок
Ошибка, содержащаяся в этом ответе, предоставляет некоторую довольно рискованную информацию - см. Здесь . Похоже, ваш сервер считает, что все запросы были выполнены локально - см .: iis.net/ConfigReference/system.webServer/httpErrors. Если вы включите CustomErrors через: <httpErrors errorMode = "Custom" />, вы увидите ту же проблему, что и у нас @ Дэвид
Джефф Далгас
0

Вы должны указать, какой тип контента вы собираетесь кэшировать. Например, вы можете кэшировать сценарии, CSS, изображения .. и т. д. так что используйте <location path ="Scripts">тег перед <system.webServer>тегом. так что ваш веб-конфиг выглядит так.

 <location path ="Scripts">
    <system.webServer>
      <staticContent>
        <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="07:00:00" />
      </staticContent>
    </system.webServer>
  </location>
  <location path ="css">
    <system.webServer>
      <staticContent>
        <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="07:00:00" />
      </staticContent>
    </system.webServer>
 </location>
Асанга Амбагаспития
источник
Это действительно решает этот вопрос?
птенцы