Ajax、戻るボタン、DOMの更新


113

JavaScriptがページAのDOMを変更する場合、ユーザーはページBに移動し、次に戻るボタンを押してページAに戻ります。ページAのDOMへの変更はすべて失われ、ユーザーは最初にサーバーから取得されたバージョンが表示されます。

それは、stackoverflow、reddit、および他の多くの人気のあるWebサイトでそのように機能します。(この質問にテストコメントを追加してから、別のページに移動し、戻るボタンを押して戻ってください-コメントは「消えてしまいます」)

これは理にかなっていますが、一部のWebサイト(apple.com、basecamphq.comなど)は、どういうわけかブラウザにページの最新の状態を提供することを強制しています。(http://www.apple.com/ca/search/?q=ipodにアクセスし、上部にある[ダウンロード]リンクをクリックしてから[戻る]ボタンをクリック-すべてのDOM更新が保持されます)

矛盾はどこから来ていますか?


興味深いことに、Appleはハッシュを変更せずに様子を思い出します。..うーん
ジェームズ・

Appleは単に応答キャッシュを操作しているように見える
BigBlondeViking 2009

他の人がすでに示唆しているように、これはjavascriptまたはajaxに関連するものではありません。正しい答えを得るには、これらのタグを削除する必要があります。
BYK、

Appleの例は貧弱です。検索領域[ex:products]を縮小し、リンクをクリックしてから押し戻すと、DOMは保持されません。多くの人が提案しているハッシュソリューションを探しています。
BigBlondeViking 2009

戻るボタンを押したとき、Appleは検索結果のどのページを表示していたかまったく覚えていません。IE7を使用します。ハッシュソリューションが必要です。参照:Facebook。
Josh Stodola、

回答:


106

1つの答え:とりわけ、アンロードイベントにより、バック/フォワードキャッシュが無効化されます。

一部のブラウザーは、いわゆる「bfcache」または「ページキャッシュ」にWebページ全体の現在の状態を保存します。これにより、[戻る]ボタンと[進む]ボタンを使用して移動するときに、ページを非常にすばやく再レンダリングし、DOMとすべてのJavaScript変数の状態を保持できます。ただし、ページにonunloadイベントが含まれている場合、それらのイベントによってページが機能しない状態になる可能性があるため、ページはbfcacheに保存されず、再ロードする必要があります(ただし、標準キャッシュからロードすることができます)。すべてのonloadハンドラーの実行を含め、最初からレンダリングされます。bfcacheを介してページに戻ると、DOMは以前の状態に保たれ、onloadハンドラーを起動する必要はありません(ページが既に読み込まれているため)。

bfcacheの動作は、Cache-Controlおよびその他のHTTPヘッダーに関して、標準のブラウザーキャッシュとは異なることに注意してください。多くの場合、ブラウザは標準のキャッシュにページを保存しない場合でも、ページをbfcacheにキャッシュします。

jQueryは自動的にアンロードイベントをウィンドウにアタッチするため、残念ながらjQueryを使用すると、DOMの保持と迅速なバック/フォワードのためにページがbfcacheに保存されなくなります。。[更新:これはjQuery 1.4で修正されたため、IEにのみ適用されます]


3
あなたはそれを完全に釘付けにしました。basedampとappleがprototypejsを使用している間、redditとstackoverflowはどちらもjqueryを使用しています。これはほとんどすべてを説明します。
lubos hasko 2009

+1興味深い(ただし、クロスブラウザーではない)質問は、開始時とは大きく異なります...
BigBlondeViking

1
Internet Explorerでも再現できるので、おそらくクロスブラウザになるでしょう。JavaScriptが有効になっているすべてのWebブラウザーがこの問題に対処しなければならなかったと確信しています。しかし、これは本当に混乱しています。あなたがそれを考えると、戻るボタンは常に、最後に見たページにすべてのDOMの更新、JavaScriptの状態などで人々を連れて行く必要があります。開発者は、アンロードイベントで何かを実行してこれを壊してはいけませんその場合、Webブラウザーはbfcacheをまったく使用しないことで問題を修正しようとすべきではありません。アンロードイベント全体が1つの大きな冗談です。メモリリークの修正に使用される時間の99%は確かです。
lubos hasko 2009

1
具体的には、IEのメモリリークです。:) jQuery unloadイベントは、Firefox 2の(完全に無関係な)バグも修正しますが、他のブラウザーでは不要です。 dev.jquery.com/ticket/3015 アウトバウンドクリックトラッキングやwebappの状態の保存など、onunloadの他の使用法を聞いたことがありますが、自分で使用する理由がなかったため、開発者がユーザーにとってサイトの速度が遅くなり、痛みが大きくなります(redditコメントページに戻ると、コメントが折りたたまれた状態にリセットされるのが嫌いです)。
マイル

1
アンロードイベントはIEにのみアタッチされ、FirefoxとChromeにはアタッチされません。Safariの最新バージョンは、開発者が何もしなくてもdom状態を保持します。
David

15

私はChromeがSafariのように動作するようにしてきましたが、機能する唯一の方法Cache-control: no-storeはヘッダーを設定することです。これにより、ユーザーが[戻る]ボタンを押すと、ブラウザはサーバーからページを再フェッチします。理想的ではありませんが、古いページが表示されるよりはましです。


5
これは、元の質問に対する正しい答えです。戻るボタンでサーバーを強制的に再読み込みする場合は、cache-control 'no-store、no-cache、must-revalidate'を使用します。Chromeはストアを必要とせず、IEは再検証が必要です。他のブラウザー(およびw3c)の場合、キャッシュなしで十分です。
2013年

3

Facebookは、ajaxリクエストのURLのハッシュ識別子を変更することでページの状態を記憶します。これらの変更はブラウザの履歴に記録されるため、ユーザーが[戻る]ボタンをクリックすると、ハッシュは以前のものに変わります。そのため、has識別子を監視し、ブラウザによって変更されたときに反応するJavaScriptが必要になることを暗示しています。 Andreas Blixtには、ハッシュ監視スクリプトがあります


今日の時点では機能していないので、Facebookの機能を知ることができます
Ravinder Payal

3

これはハッシュ(#)記号とは関係ありません。

AppleのHTTPヘッダーを確認する場合は、単にページをキャッシュしています。


Appleの例は貧弱で、ページの状態を「保存」していないため、DOMが間違って保存されているという彼の仮定
BigBlondeViking 2009

2

URLハッシュ/フラグメント識別子の使用は、AjaxとDOMの更新に依存するWebアプリケーションで状態をフック/記憶するためのかなり一般的な方法です。

Really Simple Historyプロジェクトでいくつかのアイデアを確認してください。ハッシュの変更についてURLを監視することが可能で、rshはブラウザーの違いを考慮してこれを行います。


1

Railsこれで問題が発生している人にとっては-あなたの問題はbfcacheではありません(私はそうだったと思いました)-それはturbolinks宝石です。ここに、それを削除する方法です。

うまくいけば、これにより時間を節約し、壁に頭をぶつけてしまうことができます。


0

探しているのは、ある種のURLハッシュ管理です。URLの#はクライアント側のみを対象としています。

JSで背中の状態を変更すると、URLの#のデータが更新されます。

また、ハッシュが変更されたかどうかを監視し、ハッシュの新しいデータに基づいてページの状態をロードするポーリングのタイプを追加します。

これをみて:

http://ajaxpatterns.org/Unique_URLs


3
これはハッシュ記号とは関係ありません。
Luca Matteis、

3
あなたは間違っています、彼はAJAXソリューションでページの状態を維持する最も一般的な方法を探しています。
BigBlondeViking 2009
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.