NodeJS / express: Cache dan kode status 304

92

Ketika saya memuat ulang situs web yang dibuat dengan express, saya mendapatkan halaman kosong dengan Safari (bukan dengan Chrome) karena server NodeJS mengirimi saya kode status 304.

Bagaimana mengatasi ini?

Tentu saja, ini juga bisa menjadi masalah Safari, tetapi sebenarnya berfungsi di semua situs web lain dengan baik, jadi ini juga menjadi masalah di server NodeJS saya.

Untuk menghasilkan halaman, saya menggunakan Jade dengan res.render.

Pembaruan: Sepertinya masalah ini terjadi karena Safari mengirim 'cache-control': 'max-age=0'saat memuat ulang.

Pembaruan 2: Saya sekarang memiliki solusi, tetapi apakah ada solusi yang lebih baik? Solusi:

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

Pembaruan 3: Jadi bagian kode lengkap saat ini:

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);
    }
}
h345k34cr
sumber
1
304 bukanlah masalah. Ini berarti bahwa respons Anda tidak diubah dan browser Anda beralih ke cache untuk mengambil sumber daya. Dapatkah Anda memposting kode yang relevan di mana anomali terjadi.
Akshat Jiwan Sharma
3
ya, sebenarnya tidak diubah, tetapi Safari mengosongkan cache-nya di CMD + R (reload) dan server hanya mengatakan itu tidak berubah.
h345k34cr
Bagaimana halaman kosong terkait dengan kode status 304? Node juga akan mengirim 304 ke browser lain.
pengguna568109
2
Ini terkait karena dengan 304 body tidak terkirim dan browser menggunakan cache-nya, tetapi karena tidak ada cache, Anda mendapatkan halaman kosong
h345k34cr
1
@AkshatJiwanSharma Setiap program dikembangkan untuk memenuhi kontrak pemilik produk secara tepat. Pemilik produk adalah orang yang memiliki kode dan membayar uangnya, bukan organisasi yang menulis makalah yang tidak dipedulikan oleh siapa pun. Jika kontrak mengatakan "200" maka semua status yang tidak sama dengan "200" adalah bug. Ketika ada bug, saya HARUS menulis ulang kode sampai semuanya persis seperti yang diharapkan. W3C tidak memiliki suara dalam masalah ini.
Gherman

Jawaban:

107

Solusi termudah:

app.disable('etag');

Solusi alternatif di sini jika Anda ingin kontrol lebih:

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

blented
sumber
2
Bisakah Anda menjelaskan "solusi termudah" atau memberikan referensi tentang bagaimana pengaruhnya?
Samuel Méndez
1
@ SamuelMéndez pada dasarnya menonaktifkan caching, wiki di etag memiliki banyak info bagus en.wikipedia.org/wiki/HTTP_ETag
blented
Bekerja untuk saya :)
Naveen Kumar V
3

Seperti yang Anda katakan, Safari mengirim Cache-Control: max-age=0saat memuat ulang. Express (atau lebih khusus lagi, ketergantungan Express, node-fresh) menganggap cache sudah usang ketika Cache-Control: no-cacheheader diterima, tetapi tidak melakukan hal yang sama untuk Cache-Control: max-age=0. Dari apa yang saya tahu, mungkin seharusnya begitu. Tapi saya bukan ahli caching.

Cara mengatasinya adalah mengubah (apa yang sekarang) baris 37 node-fresh/index.jsdari

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

untuk

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

Saya bercabang node-fresh dan mengungkapkan untuk menyertakan perbaikan ini dalam proyek saya package.jsonmelalui npm, Anda dapat melakukan hal yang sama. Ini garpu saya, misalnya:

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

Cabang safari-reload-fix didasarkan pada tag 3.4.7.

James P. Javery
sumber
Kerja bagus! Saya melihat bahwa express 3.5.1 menyertakan perbaikan Anda melalui node-fresh 0.2.2.
Clafou
Sebenarnya, saya salah, perbaikan Anda telah dikembalikan dan tidak benar-benar mencapai 0.2.2. Masih belum ada perbaikan segar / cepat.
Clafou
2

Saya memiliki masalah yang sama di Safari dan Chrome (satu-satunya yang telah saya uji) tetapi saya baru saja melakukan sesuatu yang tampaknya berfungsi, setidaknya saya belum dapat mereproduksi masalah sejak saya menambahkan solusi. Apa yang saya lakukan adalah menambahkan metatag ke header dengan cap waktu yang dihasilkan. Sepertinya tidak benar tapi sederhana :)

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

Perbarui PS Sejauh yang saya tahu, masalah hilang ketika saya menghapus proxy node saya (dengan proxy yang saya maksud adalah modul express.vhost dan http-proxy), yang aneh ...

pengguna907567
sumber
Saya juga menggunakan proxy Apache, ini bisa jadi masalahnya. Solusi saya adalah menonaktifkan cache untuk situs konten dengan header http.
h345k34cr
Menonaktifkan cache melalui header jelas merupakan cara yang harus dilakukan. Awalnya itu tidak berhasil untuk saya, tetapi sekarang berhasil. Dengan kata lain, saya pasti telah membuat kesalahan di suatu tempat pertama kali :)
user907567
1

Coba gunakan penjelajahan pribadi di Safari atau hapus seluruh cache / cookie Anda.

Saya mengalami beberapa masalah serupa saat menggunakan chrome ketika browser mengira situs web itu ada di cache-nya tetapi sebenarnya tidak.

Bagian dari permintaan http yang membuat server merespon 304 adalah etag. Sepertinya Safari mengirimkan etag yang benar tanpa cache yang sesuai.

sbugert.dll
sumber
yang berfungsi untuk saya ketika saya mencoba menghapus seluruh cache, terima kasih
Yuttanant Suwansiri
0

Pertanyaan lama, saya tahu. Menonaktifkan fasilitas cache tidak diperlukan dan bukan cara terbaik untuk mengelola masalah. Dengan menonaktifkan fasilitas cache, server perlu bekerja lebih keras dan menghasilkan lebih banyak lalu lintas. Juga browser dan perangkat harus bekerja lebih keras, terutama pada perangkat seluler, ini bisa menjadi masalah.

Halaman kosong dapat dengan mudah diselesaikan dengan menggunakan tombol Shift + tombol muat ulang di browser.

Halaman kosong bisa jadi akibat dari:

  • bug di kode Anda
  • saat menguji Anda menyajikan halaman kosong (Anda tidak dapat mengingat) yang di-cache oleh browser
  • bug di Safari (jika demikian, laporkan ke Apple dan jangan coba memperbaikinya sendiri)

Coba dulu tombol Shift keyboard + tombol muat ulang dan lihat apakah masalah masih ada dan tinjau kode Anda.

Codebeat
sumber