web-dev-qa-db-ja.com

(Chromeで)pushStateを使用した後、ブラウザの戻るボタンが正しく機能しない

私はJS応答でこのタイプの行を使用しています

if (history && history.pushState){
     history.pushState(null, null, '<%=j home_path %>');
}

ブラウザでbackをクリックすると、前のページの代わりに応答のJSコードが表示されます。

最後のURLのページを再リクエストするために[戻る]ボタンを機能させる方法はありますか(home_pathの前にpushStatedが含まれていますか?)

更新

this を見つけました。他にも同じ問題があるようです。History.jsでも修正されません

そこでコメントを確認します。これはクロムでのみ発生します

私が思うこと

これらすべての根源は、popstateが同じタイプのpushstateドキュメント(js応答)を要求することです。実行する必要があるのは、popstateでのHTML応答の要求です。

その他の更新:

http://railscasts.com/episodes/246-ajax-history-state を参照してください。

 $(window).bind("popstate", function() {
      $.getScript(location.href);
    });

これは問題を解決しますが、 jQueryによると$ .getScript() はajaxキャッシュなしでタイムスタンプを追加します..これにより、URLが汚染されます。再び同じ効果で。

誰でもこれを解決する方法を知っていますか?

さらに更新

私はインターネット全体で問題の痕跡を追跡し、Railsの問題を指す issue in chrome で終わりました(ただし、Firefoxは問題なく動作します)および Rails-ujs の問題で、応答にVaryヘッダーが含まれていないことに関する問題

例は here にあります

26
Nick Ginanto

私は現在遊んで遊んでいます

 response.headers['Vary'] = 'Accept'

一見すると問題を解決するようです。

誰かが同じ問題を抱えている場合は、それを確認して教えてください

12
Nick Ginanto

Popstateイベントにリスナーを追加する必要があります

window.onpopstate = function(event) {
    //load the page
};

[戻る]ボタンを押すと、URLが変更され、popstateイベントが発生します。変更されたURLと一致する詳細をpopstateリスナーにロードするのはユーザーの責任です。

素敵なポップステートの例

一部のブラウザは、ページが最初に読み込まれたときにpopstateイベントを発生させ、無限のページ読み込みループを引き起こします。これは、次のチェックを追加することで回避できます

var loadPage = window.history.state;
window.onpopstate = function(event) {
    if (loadPage) 
        //load the page
};

次に、pushStateが呼び出されたときにloadPageをtrueに設定します。

history.pushState(null, null, '<%=j home_path %>');
loadPage = true;

この手法は、html5履歴APIをサポートするすべてのブラウザーで機能します。

7
graham mendick

それはシナトラとクロームで起こりました。

それを解決する:

$.ajaxSetup({ cache: false });
3
trompa

ローカルHTMLファイルを使用してブラウザでこのコードをテストしましたが、コンソールのセキュリティエラーが発生しました。

SecurityError: The operation is insecure.
  history.pushState(null, null, '<%=j home_path %>');

ブラウザ履歴の操作が潜在的に危険な動作と見なされる可能性があることを理解できたので、これも同様に発生していないことを確認する必要があります。 Firebug JavaScriptコンソールを使用してみてください。ローカルファイルとhttp:// HTMLファイルの動作に違いがある可能性もあります。

これは、history配列の最後の要素は基本的に現在のページであるため、前のページを変更したい場合は、2つのpushState()コマンドを使用して行うことができます-最初に目的の前の要素をプッシュしてから、現在のパスをもう一度プッシュします。私があなたの問題を正しく理解したなら。

0
Okarin