NodeJS / express:キャッシュと304ステータスコード


92

Expressで作成されたWebサイトをリロードすると、NodeJSサーバーから304ステータスコードが送信されるため、Safari(Chromeではなく)で空白のページが表示されます。

これを解決する方法は?

もちろん、これはSafariの問題である可能性もありますが、実際には他のすべてのWebサイトで正常に機能するため、NodeJSサーバーでも問題になるはずです。

ページを生成するために、私はJadeを使用してい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 2013

3
はい、実際には変更されていませんが、SafariはCMD + R(リロード)でキャッシュを空にし、サーバーは変更されなかったとだけ表示します。
h345k34cr 2013

空白ページは304ステータスコードとどのように関連していますか?ノードは304を他のブラウザにも送信します。
user568109 2013

2
304では本文が送信されず、ブラウザがそのキャッシュを使用するため、これは関連していますが、キャッシュがないため、空白のページが表示されます
h345k34cr 2013

1
@AkshatJiwanSharmaどのプログラムも、製品所有者の契約を正確に満たすように開発されています。製品の所有者は、コードを所有してお金を支払う人であり、誰も気にしない論文を書く組織ではありません。契約に「200」と記載されている場合、「200」に等しくないステータスは絶対にバグです。バグがある場合は、すべてが期待どおりになるまでコードを書き直さなければなりません。W3Cはこの件に関して発言権を持っていません。
ガーマン

回答:


107

最も簡単な解決策:

app.disable('etag');

より詳細な制御が必要な場合は、こちらの代替ソリューション:

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


2
「最も簡単な解決策」について説明したり、これがどのように影響するかについてのリファレンスを提供したりできますか?
サミュエルメンデス

1
SamuelMéndez@それは基本的にキャッシュ無効、ETagの上のwikiは良い情報をたくさん持っているen.wikipedia.org/wiki/HTTP_ETag
blented

私のために働いた:)
Naveen Kumar V

3

あなたが言ったように、SafariCache-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;

私はnode-freshをフォークし、この修正をプロジェクトのpackage.jsonviaに含めるように表現しました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-fresh0.2.2を介した修正が含まれているようです。
Clafou 2014

実際、私は間違っています。あなたの修正は元に戻され、実際には0.2.2になりませんでした。まだフレッシュ/エクスプレス修正はありません。
Clafou 2014

2

SafariとChrome(私がテストした唯一のもの)でも同じ問題が発生しましたが、うまくいくように見えることをしただけで、少なくともソリューションを追加してから問題を再現することはできませんでした。私がしたことは、生成されたtimstampを使用してヘッダーにメタタグを追加することでした。正しくないようですが、それは簡単です:)

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

PSを更新する私が知る限り、ノードプロキシ(プロキシとはexpress.vhostとhttp-proxyモジュールの両方を意味します)を削除すると問題は消えますが、これは奇妙なことです...


私もApacheプロキシを使用していますが、これが問題になる可能性があります。私の回避策は、httpヘッダーのあるコンテンツサイトのキャッシュを無効にすることでした。
h345k34cr 2013年

ヘッダーを介してキャッシュを無効にすることは間違いなく進むべき道です。最初はうまくいきませんでしたが、今はうまくいきます。言い換えれば、私は最初にどこかで間違いを犯したに違いあり
ません

1

Safariでプライベートブラウジングを使用するか、キャッシュ/ Cookie全体を削除してみてください。

ブラウザがウェブサイトをキャッシュに入れていると思ったが実際には持っていなかったときに、Chromeを使用して同様の問題が発生しました。

サーバーに304を応答させるhttpリクエストの部分はetagです。Safariが対応するキャッシュを持たずに正しいetagを送信しているようです。


キャッシュ全体を削除しようとしたとき、それは私にとっては
うまくいきました

0

古い質問、私は知っています。キャッシュ機能を無効にする必要はなく、問題を管理するための最良の方法でもありません。キャッシュ機能を無効にすることにより、サーバーはよりハードに動作し、より多くのトラフィックを生成する必要があります。また、ブラウザとデバイスはよりハードに動作する必要があります。特にモバイルデバイスでは、これが問題になる可能性があります。

空のページは、ブラウザのShiftキーとリロードボタンを使用して簡単に解決できます。

空のページは、次の結果である可能性があります。

  • コードのバグ
  • テスト中に、ブラウザによってキャッシュされた空のページ(覚えていない)を提供しました
  • Safariのバグ(もしそうなら、Appleに報告してください。自分で修正しようとしないでください)

最初にShiftキーボードキー+リロードボタンを試して、問題がまだ存在するかどうかを確認し、コードを確認してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.