Powstrzymaj IIS 7.5 przed wysyłaniem kontroli maksymalnej pamięci podręcznej na kody błędów

10

Mam trochę zawartości statycznej z Max-Agedołączonymi nagłówkami kontroli pamięci podręcznej , więc klienci będą buforować zawartość statyczną. Jednak usługi IIS 7.5 nadal wysyłają ten nagłówek, gdy pojawiają się odpowiedzi na błędy zalecające klientowi buforowanie tego.

Ma to negatywny wpływ na to, że niektóre serwery proxy buforują tę odpowiedź na błąd. Mógłbym, Vary: Accept,Accept-Encodingale tak naprawdę nie rozwiązuje to głównego problemu Max-Agewychodzenia z odpowiedzi na błędy.

Obecna odpowiednia web.configsekcja IIS to:

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

Czy istnieje sposób, abym mógł to zrobić, abyśmy nie mówili klientom ani serwerom proxy, aby buforowali kody błędów 400/500?

Kyle Brandt
źródło
Czy używasz niestandardowych stron błędów?
Justin Niessner,
@Justin - Nie, nie w tym przypadku
Nick Craver
IIS 7.0 nie wysyła dla mnie Max-Age na 40 *. Nie jestem jednak pewien, czy jest to rozbieżność między wersjami IIS.
David Murdoch,
Ponadto, w jaki sposób zmusić treść statyczną do wysłania kodu błędu 500?
David Murdoch,
1
@DavidMurdoch, na przykład, widzimy 406 odpowiedzi wysłanych z nagłówkami kontroli pamięci podręcznej, gdy użytkownicy żądają javascript, ale klient akceptuje tylko typy MIME obrazu. Serwery proxy przestrzegają tej dyrektywy buforowania (zgodnie ze specyfikacją), a inni użytkownicy nie mogą pobrać skryptu.
Jarrod Dixon

Odpowiedzi:

2

Stworzyłem podstawowy zestaw testowy.

Gdy uruchamiam testy z minimalną konfiguracją Web.config w IIS 7.0 (zintegrowany tryb potokowy w .NET 4.0) wszystko mija; Cache-Controlnagłówek odpowiedzi pliku testowego jest ustawiony, privategdy Acceptnagłówek żądania nie pasuje do nagłówka pliku Content-Type.

To prowadzi mnie do przekonania, że ​​masz moduł przerywający statyczną procedurę buforowania IIS lub IIS 7.0 i 7.5 różnią się tutaj.

Oto pliki, których użyłem (sans, some-script.jsponieważ to tylko pusty plik):

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>
David Murdoch
źródło
Możemy odtworzyć twoje ustalenia za pomocą żądań do localhost - czy próbowałeś wykonać te same testy ze zdalnego komputera?
Geoff Dalgas
Tak. se.vervestudios.co/tests/se-test/test.html (uwaga dla ludzi z przyszłości, poprzedni link służył tylko do tymczasowych testów i prawdopodobnie już nie działa, przepraszam)
David Murdoch
Błąd osadzony w tej odpowiedzi ujawnia nieco ryzykowne informacje - patrz tutaj . Wygląda na to, że Twój serwer uważa, że ​​wszystkie żądania zostały wysłane lokalnie - patrz: iis.net/ConfigReference/system.webServer/httpErrors Jeśli włączysz CustomErrors przez: <httpErrors errorMode = "Custom" /> zobaczysz ten sam problem, który mamy @ David
Geoff Dalgas
0

powinieneś określić, jaki rodzaj zawartości będziesz buforować. na przykład możesz buforować skrypty, css, image ..etc. więc użyj <location path ="Scripts">tagu przed <system.webServer>tagiem. więc konfiguracja sieci wygląda tak.

 <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>
Asanga Ambagaspitiya
źródło
Czy to naprawdę dotyczy tego pytania?
pisklęta