Impedire a IIS 7.5 di inviare la Cache-Control Max-Age sui codici di errore


10

Ho alcuni contenuti statici con Max-Ageintestazioni di controllo della cache collegate in modo che i client memorizzino nella cache i contenuti statici. Tuttavia, IIS 7.5 invia ancora questa intestazione quando ci sono risposte di errore che avvisano il client di memorizzarlo nella cache.

L'effetto negativo è che alcuni proxy memorizzeranno nella cache quella risposta di errore. Potrei, Vary: Accept,Accept-Encodingma questo non risolve davvero il problema alla radice delle Max-Agerisposte agli errori.

L'attuale web.configsezione IIS pertinente è:

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

C'è un modo in cui posso farlo in modo da non dire ai client o ai proxy di memorizzare nella cache i codici di errore 400/500?


Stai utilizzando pagine di errore personalizzate?
Justin Niessner il

@Justin - No, non in questo caso
Nick Craver

IIS 7.0 non invia Max-Age su 40 * per me. Non sono sicuro se si tratti di una discrepanza tra le versioni di IIS.
David Murdoch,

Inoltre, come si forza il contenuto statico a inviare un codice di errore 500?
David Murdoch,

1
@DavidMurdoch, ad esempio, stiamo vedendo 406 risposte inviate con le intestazioni di controllo della cache quando gli utenti richiedono javascript, ma il client accetta solo tipi MIME di immagine. I proxy stanno rispettando questa direttiva di memorizzazione nella cache (come dovrebbero, secondo le specifiche) e altri utenti non sono in grado di scaricare lo script.
Jarrod Dixon

Risposte:


2

Ho creato una "suite" di prova rudimentale.

Quando eseguo i test con un Web.config minimo su IIS 7.0 (modalità pipeline integrata su .NET 4.0) tutto passa; l' Cache-Controlintestazione della risposta del file di test è impostata su privatequando l' Acceptintestazione della richiesta non corrisponde a quella del file Content-Type.

Questo mi porta a credere che tu abbia qualche modulo che interrompe la routine di cache statica di IIS o IIS 7.0 e 7.5 differiscono qui.

Ecco i file che ho usato (senza some-script.jsche sia un file vuoto):

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>

Possiamo riprodurre i tuoi risultati usando le richieste a localhost - hai provato a fare gli stessi test da una macchina remota?
Geoff Dalgas

Si l'ho fatto. se.vervestudios.co/tests/se-test/test.html (nota per le persone del futuro, il link precedente era solo a scopo di test temporaneo e probabilmente non funziona più, mi dispiace)
David Murdoch,

L'errore incorporato in quella risposta espone alcune informazioni alquanto rischiose - vedi qui . Sembra che il tuo server creda che tutte le richieste siano state emesse localmente - vedi: iis.net/ConfigReference/system.webServer/httpErrors Se abiliti CustomErrors tramite: <httpErrors errorMode = "Custom" /> vedrai lo stesso problema che stiamo riscontrando @ David
Geoff Dalgas

0

dovresti specificare quale tipo di contenuto vuoi memorizzare nella cache. ad esempio potresti memorizzare nella cache script, css, image ..etc. quindi usa il <location path ="Scripts">tag prima del <system.webServer>tag. quindi la tua configurazione web è simile a questa.

 <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>

Questo affronta davvero questa domanda?
pulcini,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.