หยุด IIS 7.5 จากการส่ง Cache-Control Max-Age ในรหัสข้อผิดพลาด


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 Niessner

@Justin - ไม่ไม่ใช่ในกรณีนี้
Nick Craver

IIS 7.0 ไม่ส่ง Max-Age ใน 40 * ให้ฉัน ฉันไม่แน่ใจว่าเป็นความแตกต่างระหว่างรุ่น IIS แม้ว่า
David Murdoch

อีกอย่างหนึ่งจะบังคับให้เนื้อหาแบบสแตติกส่งรหัสข้อผิดพลาด 500 อย่างไร
David Murdoch

1
ตัวอย่างเช่น @DavidMurdoch เราเห็น 406 คำตอบที่ส่งมาพร้อมกับส่วนหัวควบคุมแคชเมื่อผู้ใช้ร้องขอจาวาสคริปต์ แต่ลูกค้ายอมรับเฉพาะประเภท MIME ของภาพเท่านั้น ผู้รับมอบฉันทะเคารพข้อกำหนดการแคชนี้ (ตามที่ควร) และผู้ใช้รายอื่นไม่สามารถดาวน์โหลดสคริปต์ได้
Jarrod Dixon

คำตอบ:


2

ฉันสร้าง "ชุด" ขั้นพื้นฐานสำหรับการทดสอบ

เมื่อฉันเรียกใช้การทดสอบด้วย Web.config ที่น้อยที่สุดบน IIS 7.0 (โหมด pipline รวมใน. NET 4.0) ทุกอย่างผ่านไป ไฟล์ทดสอบของCache-Controlหัวข้อการตอบสนองมีการตั้งค่าprivateเมื่อมันของคำขอของส่วนหัวไม่ตรงกับของไฟล์AcceptContent-Type

สิ่งนี้ทำให้ฉันเชื่อว่าคุณมีบางโมดูลที่ขัดจังหวะรูทีนการแคชแบบคงที่ของ IIS หรือ IIS 7.0 และ 7.5 แตกต่างกันที่นี่

นี่คือไฟล์ที่ฉันใช้ (sans 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 - คุณได้ลองทำแบบทดสอบเดียวกันจากเครื่องระยะไกลแล้วหรือยัง?
Geoff Dalgas

ใช่ฉันทำ. se.vervestudios.co/tests/se-test/test.html (หมายเหตุผู้คนในอนาคตการเชื่อมโยงก่อนหน้านี้สำหรับวัตถุประสงค์ในการทดสอบเพียงชั่วคราวและอาจจะไม่ทำงานอีกต่อไปแล้วขออภัย)
เดวิดเมอร์ด็

ข้อผิดพลาดที่ฝังตัวอยู่ในการตอบสนองที่ exposes ข้อมูลค่อนข้างมีความเสี่ยงบาง - ดูที่นี่ ดูเหมือนว่าเซิร์ฟเวอร์ของคุณเชื่อว่าคำขอทั้งหมดออกในเครื่อง - ดู: iis.net/ConfigReference/system.webServer/httpErrors หากคุณเปิดใช้งาน CustomErrors ผ่าน: <httpErrors errorMode = "Custom" /> คุณจะเห็นปัญหาเดียวกันกับที่เรามี @ David
Geoff Dalgas

0

คุณควรระบุประเภทของเนื้อหาที่คุณกำลังจะแคช ตัวอย่างเช่นคุณสามารถแคชสคริปต์, CSS, รูปภาพ .. ฯลฯ ดังนั้นใช้<location path ="Scripts">แท็กหน้า<system.webServer>แท็ก ดังนั้นเว็บ config ของคุณจะมีลักษณะเช่นนี้

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

นั่นตอบคำถามนี้จริง ๆ หรือไม่?
ลูกไก่
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.