web-dev-qa-db-ja.com

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

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

これを解決する方法?

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

ページを生成するには、res.renderでJadeを使用しています。

更新: 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);
    }
}
76
h345k34cr

最も簡単なソリューション:

app.disable('etag');

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

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

76
blented

あなたが言ったように、Safariはリロード時にCache-Control:max-age = 0を送信します。 Express(より具体的には、Expressの依存関係、ノードフレッシュ)は、Cache-Control:no-cacheヘッダーが受信されたときにキャッシュが古くなっていると見なしますが、Cache-Control:max-age = 0では同じことを行いません。私が言えることから、おそらくそうすべきです。しかし、私はキャッシングの専門家ではありません。

修正は、node-fresh/index.jsの(現在の)行37を変更することです

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を分岐し、npmを介してこの修正をプロジェクトのpackage.jsonに含めることを表明しました。同じことができます。ここに私のフォークがあります、例えば:

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

Safari-reload-fixブランチは3.4.7タグに基づいています。

3
James P. Javery

SafariとChrome(テストした唯一のもの)で同じ問題が発生しましたが、動作するように見えることをしただけで、少なくとも追加してから問題を再現できませんでした解決。私がやったのは、生成されたティムスタンプとともにヘッダーにメタタグを追加することでした。正しくは見えませんが、簡単です:)

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

更新 P.S私が知る限り、ノードプロキシを削除すると問題がなくなります(プロキシとはexpress.vhostとhttp-proxyモジュールの両方を意味します)。

2
user907567

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

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

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

1
sbugert

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

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

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

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

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

0
Codebeat

これ...これが最も簡単な方法です...

function force200Responses(req, res, next) { req.headers['if-none-match'] = 'no-match-for-this'; next(); }

app.use(force200Responses)

未来の私、大歓迎です。

0
Augie Gardner