NodeJS / express: Bộ nhớ đệm và mã trạng thái 304


92

Khi tôi tải lại một trang web được tạo bằng express, tôi nhận được một trang trống với Safari (không phải với Chrome) vì máy chủ NodeJS gửi cho tôi mã trạng thái 304.

Làm thế nào để giải quyết điều này?

Tất nhiên, đây cũng có thể chỉ là một vấn đề của Safari, nhưng thực tế nó hoạt động tốt trên tất cả các trang web khác, vì vậy nó cũng phải là một vấn đề trên máy chủ NodeJS của tôi.

Để tạo các trang, tôi đang sử dụng Jade với res.render.

Cập nhật: Có vẻ như sự cố này xảy ra do Safari gửi 'cache-control': 'max-age=0'khi tải lại.

Cập nhật 2: Tôi hiện có một giải pháp khác, nhưng có giải pháp nào tốt hơn không? Cách giải quyết:

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

Cập nhật 3: Vì vậy, phần mã hoàn chỉnh hiện là:

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 không phải là một vấn đề. Nó chỉ đơn giản có nghĩa là phản hồi của bạn không được sửa đổi và trình duyệt của bạn chuyển sang bộ nhớ cache để tìm nạp tài nguyên. Bạn có thể đăng đoạn mã liên quan mà sự bất thường đang xảy ra.
Akshat Jiwan Sharma

3
vâng, thực sự nó không được sửa đổi, nhưng Safari xóa bộ nhớ cache của nó trên CMD + R (tải lại) và máy chủ chỉ cho biết nó không thay đổi.
h345k34cr

Trang trống liên quan đến mã trạng thái 304 như thế nào? Node cũng sẽ gửi 304 đến các trình duyệt khác.
user568109

2
Nó có liên quan bởi vì với 304 cơ thể không được gửi và trình duyệt sử dụng bộ nhớ cache của nó, nhưng vì không có bộ nhớ cache, bạn sẽ có một trang trống
h345k34cr

1
@AkshatJiwanSharma Bất kỳ chương trình nào cũng được phát triển để đáp ứng chính xác hợp đồng của chủ sở hữu sản phẩm. Chủ sở hữu sản phẩm là người sở hữu mã và trả tiền, không phải tổ chức nào đó viết giấy tờ mà không ai quan tâm. Nếu hợp đồng ghi "200" thì tuyệt đối bất kỳ trạng thái nào không bằng "200" đều là lỗi. Khi có lỗi, tôi PHẢI viết lại mã cho đến khi mọi thứ chính xác như mong đợi. W3C không có tiếng nói trong vấn đề này.
Gherman

Câu trả lời:


107

Giải pháp dễ dàng nhất:

app.disable('etag');

Giải pháp thay thế ở đây nếu bạn muốn kiểm soát nhiều hơn:

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


2
Bạn có thể giải thích "giải pháp dễ nhất" hoặc đưa ra tài liệu tham khảo về cách điều này ảnh hưởng đến?
Samuel Méndez

1
@ SamuelMéndez về cơ bản nó vô hiệu hóa bộ nhớ đệm, wiki trên etag có rất nhiều thông tin tốt en.wikipedia.org/wiki/HTTP_ETag
blented 12/1218

Làm việc cho tôi :)
Naveen Kumar V

3

Như bạn đã nói, Safari sẽ gửi Cache-Control: max-age=0khi tải lại. Express (hoặc cụ thể hơn, phụ thuộc của Express, node-fresh) coi bộ nhớ cache đã cũ khi Cache-Control: no-cachenhận được tiêu đề, nhưng nó không làm như vậy đối với Cache-Control: max-age=0. Từ những gì tôi có thể nói, nó có lẽ nên. Nhưng tôi không phải là chuyên gia về bộ nhớ đệm.

Cách khắc phục là thay đổi (hiện tại là) dòng 37 của node-fresh/index.jstừ

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

đến

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

Tôi đã chuyển đổi nút mới và thể hiện để đưa bản sửa lỗi này vào package.jsonthông qua dự án của tôi npm, bạn có thể làm như vậy. Đây là những cái nĩa của tôi, ví dụ:

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

Nhánh safari-tải lại-sửa lỗi dựa trên thẻ 3.4.7.


Công việc tuyệt vời! Tôi thấy rằng express 3.5.1 bao gồm bản sửa lỗi của bạn thông qua node-fresh 0.2.2.
Clafou

Trên thực tế, tôi đã nhầm, bản sửa lỗi của bạn đã được hoàn nguyên và không thực sự chuyển thành 0,2.2. Vẫn không có sửa chữa mới / nhanh.
Clafou

2

Tôi đã gặp sự cố tương tự trong Safari và Chrome (những thứ duy nhất tôi đã thử nghiệm) nhưng tôi vừa làm một cái gì đó có vẻ hoạt động, ít nhất là tôi đã không thể tái tạo sự cố kể từ khi tôi thêm giải pháp. Những gì tôi đã làm là thêm thẻ meta vào tiêu đề với nhãn thời gian đã tạo. Có vẻ không đúng nhưng nó đơn giản :)

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

Cập nhật PS Theo như tôi có thể nói, sự cố sẽ biến mất khi tôi xóa proxy nút của mình (theo proxy, tôi có nghĩa là cả express.vhost và mô-đun http-proxy), điều này thật kỳ lạ ...


Tôi cũng sử dụng proxy Apache, đây có thể là vấn đề. Cách giải quyết của tôi là chỉ tắt bộ nhớ đệm cho các trang web nội dung có tiêu đề http.
h345k34cr

Vô hiệu hóa bộ nhớ cache thông qua các tiêu đề chắc chắn là cách tốt nhất. Lúc đầu nó không hiệu quả với tôi nhưng bây giờ thì có. Nói cách khác tôi có lẽ đã làm sai ở đâu đó lần đầu tiên xung quanh :)
user907567

1

Hãy thử sử dụng duyệt web riêng tư trong Safari hoặc xóa toàn bộ bộ nhớ cache / cookie của bạn.

Tôi đã gặp một số vấn đề tương tự khi sử dụng chrome khi trình duyệt nghĩ rằng nó có trang web trong bộ nhớ cache của nó nhưng thực tế thì không.

Phần của yêu cầu http khiến máy chủ phản hồi 304 là etag. Có vẻ như Safari đang gửi đúng etag mà không có bộ nhớ đệm tương ứng.


rằng công trình cho tôi khi tôi đã cố gắng để xóa toàn bộ bộ nhớ cache, nhờ
Yuttanant Suwansiri

0

Câu hỏi cũ, tôi biết. Vô hiệu hóa cơ sở bộ nhớ cache là không cần thiết và không phải là cách tốt nhất để quản lý vấn đề. Bằng cách vô hiệu hóa cơ sở bộ nhớ cache, máy chủ cần làm việc chăm chỉ hơn và tạo ra nhiều lưu lượng truy cập hơn. Ngoài ra, trình duyệt và thiết bị cần phải hoạt động nhiều hơn, đặc biệt là trên thiết bị di động, điều này có thể là một vấn đề.

Trang trống có thể được giải quyết dễ dàng bằng cách sử dụng phím Shift + nút tải lại trên trình duyệt.

Trang trống có thể là kết quả của:

  • một lỗi trong mã của bạn
  • trong khi kiểm tra, bạn đã phân phát một trang trống (bạn không thể nhớ) được trình duyệt lưu vào bộ nhớ cache
  • một lỗi trong Safari (nếu có, vui lòng báo cáo cho Apple và đừng cố tự sửa)

Trước tiên, hãy thử phím Shift + nút tải lại và xem sự cố còn tồn tại hay không và xem lại mã của bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.