Verhindern Sie, dass IIS 7.5 das maximale Alter der Cache-Steuerung für Fehlercodes sendet

10

Ich habe statischen Inhalt mit Cache-Steuerelement- Max-AgeHeadern, damit Clients den statischen Inhalt zwischenspeichern. IIS 7.5 sendet diesen Header jedoch weiterhin, wenn Fehlerantworten vorliegen, die den Client auffordern, dies zwischenzuspeichern.

Dies hat den negativen Effekt, dass einige Proxys diese Fehlerantwort zwischenspeichern. Ich könnte, Vary: Accept,Accept-Encodingaber dies behebt nicht wirklich das Grundproblem Max-Age, Fehlerantworten zu beantworten.

Der aktuell relevante IIS- web.configAbschnitt lautet:

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

Gibt es eine Möglichkeit, wie ich es schaffen kann, damit wir Clients oder Proxys nicht anweisen, 400/500 Fehlercodes zwischenzuspeichern?

Kyle Brandt
quelle
Verwenden Sie benutzerdefinierte Fehlerseiten?
Justin Niessner
@ Justin - Nein, nicht in diesem Fall
Nick Craver
IIS 7.0 sendet für mich kein Max-Age auf 40 *. Ich bin mir nicht sicher, ob es sich um eine Diskrepanz zwischen IIS-Versionen handelt.
David Murdoch
Wie erzwingt man statischen Inhalt, um einen 500-Fehlercode zu senden?
David Murdoch
1
@DavidMurdoch Zum Beispiel werden 406 Antworten mit Cache-Steuerelement-Headern gesendet, wenn Benutzer Javascript anfordern, der Client jedoch nur Image-MIME-Typen akzeptiert. Proxys respektieren diese Caching-Direktive (wie sie es sollten, gemäß der Spezifikation) und andere Benutzer können das Skript nicht herunterladen.
Jarrod Dixon

Antworten:

2

Ich habe eine rudimentäre Testsuite erstellt.

Wenn ich die Tests mit einer minimalen Web.config unter IIS 7.0 (Integrierter Pipline-Modus unter .NET 4.0) ausführe, ist alles erfolgreich. Der Antwortheader der Testdatei Cache-Controlwird auf gesetzt, privatewenn der AcceptHeader der Anforderung nicht mit dem der Datei übereinstimmt Content-Type.

Dies lässt mich glauben, dass ein Modul die statische Caching-Routine von IIS unterbricht oder dass sich IIS 7.0 und 7.5 hier unterscheiden.

Hier sind die Dateien, die ich verwendet habe (ohne, some-script.jsda es sich nur um eine leere Datei handelt):

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
quelle
Wir können Ihre Ergebnisse mithilfe von Anfragen an localhost reproduzieren. Haben Sie versucht, dieselben Tests von einem Remotecomputer aus durchzuführen?
Geoff Dalgas
Ja, habe ich. se.vervestudios.co/tests/se-test/test.html (Hinweis für Menschen der Zukunft, der vorherige Link diente nur zu vorübergehenden Testzwecken und funktioniert wahrscheinlich nicht mehr, sorry)
David Murdoch
Der in diese Antwort eingebettete Fehler enthüllt einige etwas riskante Informationen - siehe hier . Es scheint , dass der Server glaubt , alle Anfragen lokal ausgegeben wurden - siehe: iis.net/ConfigReference/system.webServer/httpErrors Wenn Sie Custom über aktivieren: <httperrors Errormode = „Custom“ /> werden Sie das gleiche Problem sehen wir haben , werden @ David
Geoff Dalgas
0

Sie sollten angeben, welche Art von Inhalt Sie zwischenspeichern möchten. Zum Beispiel könnten Sie Skripte, CSS, Image usw. zwischenspeichern. Verwenden Sie also das <location path ="Scripts">Tag vor dem <system.webServer>Tag. Ihre Webkonfiguration sieht also so aus.

 <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
quelle
Geht das wirklich auf diese Frage ein?
Küken