Evite que IIS 7.5 envíe la antigüedad máxima de Cache-Control en códigos de error

10

Tengo contenido estático con Max-Ageencabezados de control de caché adjuntos para que los clientes almacenen en caché el contenido estático. Sin embargo, IIS 7.5 aún envía este encabezado cuando hay respuestas de error que aconsejan al cliente que lo guarde en caché.

Tiene el efecto negativo de que algunos servidores proxy almacenarán en caché esa respuesta de error. Podría, Vary: Accept,Accept-Encodingpero esto realmente no aborda el problema raíz de Max-Agesalir con respuestas de error.

La web.configsección de IIS relevante actual es:

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

¿Hay alguna manera de hacerlo para que no le digamos a los clientes o representantes que guarden en caché los códigos de error 400/500?

Kyle Brandt
fuente
¿Estás usando páginas de error personalizadas?
Justin Niessner
@Justin - No, no en este caso
Nick Craver
IIS 7.0 no envía Max-Age en 40 * para mí. Sin embargo, no estoy seguro de si es una discrepancia entre las versiones de IIS.
David Murdoch
Además, ¿cómo se fuerza el contenido estático a enviar un código de error 500?
David Murdoch
1
@DavidMurdoch, por ejemplo, estamos viendo 406 respuestas enviadas con encabezados de control de caché cuando los usuarios solicitan JavaScript, pero el cliente solo acepta tipos de imágenes MIME. Los representantes respetan esta directiva de almacenamiento en caché (como deberían, según las especificaciones) y otros usuarios no pueden descargar el script.
Jarrod Dixon

Respuestas:

2

Creé una "suite" de prueba rudimentaria.

Cuando ejecuto las pruebas con un mínimo de Web.config en IIS 7.0 (modo de tubería integrada en .NET 4.0) todo pasa; el Cache-Controlencabezado de respuesta del archivo de prueba está configurado privatecuando el Acceptencabezado de su solicitud no coincide con el del archivo Content-Type.

Esto me lleva a creer que tiene algún módulo que interrumpe la rutina de almacenamiento en caché estático de IIS o que IIS 7.0 y 7.5 difieren aquí.

Aquí están los archivos que usé (sin ellos, some-script.jsya que es solo un archivo vacío):

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
fuente
Podemos reproducir sus hallazgos mediante solicitudes a localhost. ¿Ha intentado hacer las mismas pruebas desde una máquina remota?
Geoff Dalgas
Sí, lo hice. se.vervestudios.co/tests/se-test/test.html (nota para las personas del futuro, el enlace anterior era solo para fines de pruebas temporales y probablemente ya no funcione, lo siento)
David Murdoch
El error incrustado en esa respuesta expone información algo arriesgada: consulte aquí . Parece que su servidor cree que todas las solicitudes se emitieron localmente; consulte: iis.net/ConfigReference/system.webServer/httpErrors Si habilita CustomErrors a través de: <httpErrors errorMode = "Custom" /> verá el mismo problema que estamos teniendo @ David
Geoff Dalgas
0

debe especificar qué tipo de contenido va a almacenar en caché. por ejemplo, puede almacenar en caché Scripts, css, image ..etc. así que usa la <location path ="Scripts">etiqueta antes de la <system.webServer>etiqueta. entonces su configuración web se ve así.

 <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
fuente
¿Eso realmente aborda esta pregunta?
pollitos