NodeJS / express: แคชและรหัสสถานะ 304


92

เมื่อฉันโหลดเว็บไซต์ที่สร้างด้วย Express ซ้ำฉันจะได้รับหน้าว่างพร้อม Safari (ไม่ใช่ใน Chrome) เนื่องจากเซิร์ฟเวอร์ NodeJS ส่งรหัสสถานะ 304 มาให้ฉัน

วิธีแก้ปัญหานี้?

แน่นอนว่านี่อาจเป็นเพียงปัญหาของ Safari แต่จริงๆแล้วมันทำงานบนเว็บไซต์อื่น ๆ ทั้งหมดได้ดีดังนั้นจึงต้องมีปัญหากับเซิร์ฟเวอร์ NodeJS ของฉันด้วย

res.renderในการสร้างหน้าเว็บที่ผมใช้กับหยก

อัปเดต:ดูเหมือนว่าปัญหานี้เกิดขึ้นเนื่องจาก Safari ส่ง'cache-control': 'max-age=0'เมื่อโหลดซ้ำ

อัปเดต 2:ตอนนี้ฉันมีวิธีแก้ปัญหา แต่มีวิธีแก้ปัญหาที่ดีกว่านี้หรือไม่ วิธีแก้ปัญหา:

app.get('/:language(' + content.languageSelector + ')/:page', function (req, res)
{
    // Disable caching for content files
    res.header("Cache-Control", "no-cache, no-store, must-revalidate");
    res.header("Pragma", "no-cache");
    res.header("Expires", 0);

    // rendering stuff here…
}

อัปเดต 3: ดังนั้นส่วนรหัสที่สมบูรณ์ในขณะนี้คือ:

app.get('/:language(' + content.languageSelector + ')/:page', pageHandle);

function pageHandle (req, res)
{
    var language = req.params.language;
    var thisPage = content.getPage(req.params.page, language);

    if (thisPage)
    {
        // Disable caching for content files
        res.header("Cache-Control", "no-cache, no-store, must-revalidate");
        res.header("Pragma", "no-cache");
        res.header("Expires", 0);

        res.render(thisPage.file + '_' + language, {
            thisPage : thisPage,
            language: language,
            languages: content.languages,
            navigation: content.navigation,
            footerNavigation: content.footerNavigation,
            currentYear: new Date().getFullYear()
        });
    }
    else
    {
        error404Handling(req, res);
    }
}

1
304 ไม่ใช่ปัญหา หมายความว่าการตอบกลับของคุณไม่ได้รับการแก้ไขและเบราว์เซอร์ของคุณจะเปลี่ยนเป็นแคชเพื่อดึงทรัพยากร คุณสามารถโพสต์รหัสที่เกี่ยวข้องซึ่งเกิดความผิดปกติได้หรือไม่
Akshat Jiwan Sharma

3
ใช่จริงๆแล้วมันไม่ได้แก้ไข แต่ Safari ล้างแคชบน CMD + R (โหลดซ้ำ) และเซิร์ฟเวอร์บอกเพียงว่าไม่เปลี่ยนแปลง
h345k34cr

หน้าว่างเกี่ยวข้องกับรหัสสถานะ 304 อย่างไร โหนดจะส่ง 304 ไปยังเบราว์เซอร์อื่นด้วย
user568109

2
มันเกี่ยวข้องกันเพราะด้วย 304 ร่างกายไม่ได้ถูกส่งและเบราว์เซอร์ใช้แคช แต่เนื่องจากไม่มีแคชคุณจะได้รับหน้าว่าง
h345k34cr

1
@AkshatJiwanSharma โปรแกรมใด ๆ ก็ได้รับการพัฒนาให้ตรงตามสัญญาของเจ้าของผลิตภัณฑ์ทุกประการ เจ้าของผลิตภัณฑ์คือผู้ที่เป็นเจ้าของรหัสและจ่ายเงินไม่ใช่บางองค์กรที่เขียนเอกสารที่ไม่มีใครสนใจ หากสัญญาระบุว่า "200" สถานะใดก็ตามที่ไม่เท่ากับ "200" ถือเป็นข้อบกพร่อง เมื่อมีข้อผิดพลาดฉันต้องเขียนโค้ดใหม่จนกว่าทุกอย่างจะเป็นไปตามที่คาดไว้ W3C ไม่มีการพูดในเรื่องนี้
Gherman

คำตอบ:


107

ทางออกที่ง่ายที่สุด:

app.disable('etag');

ทางเลือกอื่นหากคุณต้องการควบคุมเพิ่มเติม:

http://vlasenko.org/2011/10/12/expressconnect-static-set-last-modified-to-now-to-avoid-304-not-modified/


2
คุณช่วยอธิบาย "วิธีแก้ปัญหาที่ง่ายที่สุด" หรือให้ข้อมูลอ้างอิงว่าสิ่งนี้ส่งผลอย่างไร
Samuel Méndez

1
@ SamuelMéndezปิดการใช้งานแคชพื้น, วิกิพีเดียใน etag ที่มีจำนวนมากของข้อมูลที่ดีen.wikipedia.org/wiki/HTTP_ETag
blented

ทำงานให้ฉัน :)
Naveen Kumar V

3

อย่างที่คุณบอก Safari ส่งCache-Control: max-age=0เมื่อโหลดซ้ำ Express (หรือโดยเฉพาะอย่างยิ่งการอ้างอิงของ Express, node-fresh) จะพิจารณาแคชเก่าเมื่อCache-Control: no-cacheได้รับส่วนหัว แต่จะไม่ทำเช่นเดียวกันสำหรับCache-Control: max-age=0. จากสิ่งที่ฉันสามารถบอกได้ก็น่าจะ แต่ฉันไม่ใช่ผู้เชี่ยวชาญในการแคช

การแก้ไขคือการเปลี่ยน (ปัจจุบันคืออะไร) บรรทัดที่ 37 node-fresh/index.jsจาก

if (cc && cc.indexOf('no-cache') !== -1) return false;  

ถึง

if (cc && (cc.indexOf('no-cache') !== -1 ||
  cc.indexOf('max-age=0') !== -1)) return false;

ฉันแยกโหนดสดและแสดงเพื่อรวมการแก้ไขนี้ในโครงการของฉันpackage.jsonผ่านnpmคุณสามารถทำได้เช่นเดียวกัน นี่คือส้อมของฉันตัวอย่างเช่น:

https://github.com/stratusdata/node-fresh https://github.com/stratusdata/express#safari-reload-fix

สาขา safari-reload-fix ขึ้นอยู่กับแท็ก 3.4.7


การทำงานที่ดี! ฉันเห็นว่า Express 3.5.1 มีการแก้ไขของคุณผ่าน node-fresh 0.2.2
Clafou

อันที่จริงฉันผิดการแก้ไขของคุณถูกเปลี่ยนกลับแล้วและไม่ได้ทำให้เป็น 0.2.2 ยังไม่มีการแก้ไขใหม่ / ด่วน
Clafou

2

ฉันมีปัญหาเดียวกันใน Safari และ Chrome (สิ่งเดียวที่ฉันทดสอบ) แต่ฉันเพิ่งทำบางอย่างที่ดูเหมือนจะใช้งานได้อย่างน้อยฉันก็ไม่สามารถสร้างปัญหาซ้ำได้ตั้งแต่ฉันเพิ่มวิธีแก้ปัญหา สิ่งที่ฉันทำคือเพิ่มเมตาแท็กในส่วนหัวด้วย timstamp ที่สร้างขึ้น ดูเหมือนจะไม่ถูกต้อง แต่มันง่าย :)

<meta name="304workaround" content="2013-10-24 21:17:23">

อัปเดต PS เท่าที่ฉันบอกได้ปัญหาจะหายไปเมื่อฉันลบพร็อกซีโหนดของฉัน (โดยพร็อกซีฉันหมายถึงทั้งโมดูล express.vhost และ http-proxy) ซึ่งแปลก ...


ฉันใช้พร็อกซี Apache ด้วยซึ่งอาจเป็นปัญหาได้ วิธีแก้ปัญหาของฉันคือปิดการใช้งานการแคชสำหรับไซต์เนื้อหาที่มีส่วนหัว http
h345k34cr

การปิดใช้งานแคชผ่านส่วนหัวเป็นวิธีที่แน่นอน ตอนแรกมันไม่ได้ผลสำหรับฉัน แต่ตอนนี้มันทำได้ กล่าวอีกนัยหนึ่งฉันคงเคยทำผิดพลาดที่ไหนสักแห่งเป็นครั้งแรก :)
user907567

1

ลองใช้การท่องเว็บแบบส่วนตัวใน Safari หรือลบแคช / คุกกี้ทั้งหมดของคุณ

ฉันมีปัญหาที่คล้ายกันในการใช้ chrome เมื่อเบราว์เซอร์คิดว่ามีเว็บไซต์อยู่ในแคช แต่จริงๆแล้วไม่มี

ส่วนของคำขอ http ที่ทำให้เซิร์ฟเวอร์ตอบสนอง 304 คือ etag ดูเหมือนว่า Safari กำลังส่ง etag ที่ถูกต้องโดยไม่ต้องมีแคชที่เกี่ยวข้อง


ที่เหมาะกับฉันเมื่อฉันพยายามลบแคชทั้งหมดขอบคุณ
ยุทธนันท์สุวรรณศิริ

0

คำถามเก่าฉันรู้ ไม่จำเป็นต้องปิดใช้งานแคชและไม่ใช่วิธีที่ดีที่สุดในการจัดการปัญหา การปิดใช้งานสิ่งอำนวยความสะดวกแคชทำให้เซิร์ฟเวอร์ต้องทำงานหนักขึ้นและสร้างทราฟฟิกเพิ่มขึ้น นอกจากนี้เบราว์เซอร์และอุปกรณ์ยังต้องทำงานหนักขึ้นโดยเฉพาะบนอุปกรณ์เคลื่อนที่ซึ่งอาจเป็นปัญหาได้

หน้าว่างสามารถแก้ไขได้อย่างง่ายดายโดยใช้ปุ่ม Shift + ปุ่มรีโหลดที่เบราว์เซอร์

หน้าว่างอาจเป็นผลมาจาก:

  • จุดบกพร่องในโค้ดของคุณ
  • ในขณะทดสอบคุณแสดงหน้าที่ว่างเปล่า (คุณจำไม่ได้) ที่เบราว์เซอร์แคชไว้
  • ข้อบกพร่องใน Safari (ถ้าเป็นเช่นนั้นโปรดรายงานไปยัง Apple และอย่าพยายามแก้ไขด้วยตนเอง)

ลองใช้ปุ่ม Shift คีย์บอร์ด + ปุ่มโหลดซ้ำก่อนและดูว่าปัญหายังคงมีอยู่หรือไม่และตรวจสอบโค้ดของคุณ

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