10

私のウェブサイトのパフォーマンス/応答性を改善するために、AJAX、replaceState、pushState、および popstate リスナーを使用して部分的なページ読み込みを実装しました。

基本的に、ページの中央部分 (HTML) を状態オブジェクトとして履歴に保存します。リンクがクリックされると、サーバーにページの中央部分のみを要求し (これらの要求を別の Accept ヘッダーで識別します)、それを JavaScript に置き換えます。popstate で、前の中央部分をつかみ、dom に押し戻します。

これはほとんど問題なく動作しますが、私が立ち往生している特定の問題を発見しました。説明するのが少し複雑なので、これがあまり明確でない場合は申し訳ありません。

ほとんどのページに検索フォームがあります。ajax による部分的なページの読み込みは GET リクエストでのみ行われ、フォームは POST を実行し、結果としてページ全体が読み込まれます。

次の一連のページをナビゲートすると、中央のコンテンツのみで構成され、周囲の DOM がまったくない不正な部分ページに行き着きます。

ホームページから開始 (ページ全体の読み込みを介して) - 検索を実行します (post-redirect-get)
検索結果に移動します (ページ全体の読み込みを介して) - 次に [ホーム] をクリックします
ホーム ページに戻ります (動的 get を介して) - クリックしますブラウザに戻る
検索結果 (popstate リスナーから) - ブラウザに戻るをクリックします
不正なホームページです。

不正なホームページが表示されると、popstate リスナーがまったく存在しません。

私が考えているのは、ホームページの 2 番目のロード (動的、部分的) がブラウザーによってキャッシュされており、ページ全体が戻ると、ブラウザーは完全なページではなく、キャッシュされた部分的な応答を表示するだけです。 .

これを改善するために、応答に Vary: Accept ヘッダーを追加して、accept ヘッダーに基づいてコンテンツが変更される可能性があることをブラウザーに知らせます。また、部分的に読み込まれたコンテンツに Cache-Control max-age=0、pragma no-cache、および過去の有効期限を追加して、ブラウザーがこれをキャッシュしないように強制しましたが、どれも解決しません。

残念ながら、私の会社は開発サーバーへの外部トラフィックを許可していないため、問題を示すことはできません。ここでさまざまな同様の質問を見てきましたが、まったく同じものはなく、提案された解決策も機能していないようです。

無意味なパラメーター (blah=blah) を動的 GET 要求に追加すると、問題が解決します。しかし、これは私がやりたくない醜いハックです。これはキャッシングの問題だと思うので、ヘッダーで解決できるようです。誰が何が起こっているのか説明できますか?

4

3 に答える 3

9

それはキャッシングの問題です。応答ヘッダー Cache-Control をno-cacheorに設定するmax-age=0と、問題は FF では発生しませんが (あなたが言ったように)、Chrome では持続します。

私のために働いたヘッダーは Cache-Control:no-storeです。これは、すべてのブラウザーで一貫して実装されているわけではありません (no-cache と no-store の違いを尋ねる質問を見つけることができます) が、Chrome でも期待どおりの結果が得られます。

于 2012-07-09T10:31:17.303 に答える
1

リンクがクリックされると、サーバーにページの中央部分だけを要求し (これらの要求を別の Accept ヘッダーで識別します)、それを JavaScript に置き換えます。

素晴らしい。それが RESTful な方法です。しかし、これを機能させるには、あと 1 つVary、応答にヘッダーを追加する必要があります。

Vary: Accept

これは、別の Accept ヘッダーを持つ要求が別の応答を受け取る可能性があることをブラウザーに伝えます。2 つの要求は異なる Accept ヘッダーを使用するため、ブラウザー (およびキャッシング プロキシ) は応答を別々にキャッシュします。

setting とは異なりCache-Control: no-store、これでもキャッシュを使用できます。

于 2014-02-18T19:15:45.067 に答える
1

同様の問題がありました。私はWebベースのウィザードを構築しており、jquery ajaxを使用して各ステップをロードしています(バックエンドのASP.NET MVC)。

初期ルートは /Questions/Show のようなもので、ページ全体をロードして最初の質問 (質問 0) を表示します。ユーザーが次の画像をクリックすると、URL /Questions/Save/0 で jquery .load() が実行されます。これにより、回答が保存され、次の質問の部分ビューが返されます。次の保存では、/Questions/Save/1 で jquery .load() を実行します ...

ユーザーが前後に移動できるように、History.js を実装しました。質問番号を状態データに格納します。statechange を検出すると (および状態の質問番号がページの内容と異なる場合)、jquery .load() を実行して正しい質問をロードします。

最初は、最初のページがロードされたときと同じルートを使用していました (/Questions/Show/X X は質問番号です)。バックエンドで、それが ajax リクエストであるかどうかを検出し、そうであれば、完全なビューではなく部分的なビューを返しました。ここで問題が発生しました。質問 3 で、前に戻って次に進み、www.google.com に移動し、[戻る] ボタンを押したとします。質問 3 が表示されましたが、それは部分ビューでした。ブラウザーがそのルートの部分ビューをキャッシュしたためです。

私の解決策は、ajax 呼び出し用に別のルート /Questions/Load/X を作成することでした (バックエンドで共通のコードを使用していました)。2 つの異なるルート (非 ajax の場合は /Questions/Show、ajax の場合は /Questions/Load) を使用すると、ブラウザーは上記の状況でページ全体を正しく表示します。

したがって、おそらく同様の解決策がうまくいくでしょう...つまり、ホームページに2つの異なるルート-1つはフルページ用、もう1つは部分用です。それが役立つことを願っています。

于 2012-11-21T17:10:30.613 に答える