2016-11-21 2 views
2

JS/ReactJSアプリケーションでbeforeunloadas customaryにイベントリスターを追加しました。この関数は、内部のunSaved状態に応じて確認ダイアログを追加します。* onbeforeunload *はSafari(macOS)にキャッシュされていますか?

ChromeやFirefox(MacOS /デスクトップ)でも問題なく動作します。しかし、Safariで

、:

  • 初めて、後続の試みで、まだイベントハンドラの「私が利用する」(unSaved==trueながら、私はページを離れる)aspectedとして、それが正常に動作し、
  • ページをunSaved==trueのままにしておくと、Safariは何も確認を求めません。
  • 私は(同じ以前のURLを持つ)新しいタブに移動し、再び第1の時間は動作しますが、その後の回にはありません...

何奇妙です:私は私の追加されたイベント機能があることがわかります毎回実際にテストが行​​われているので、サファリで毎回呼び出されます。console.log

私の唯一の可能な推測は、Safariがどういうわけかタブの確認応答をキャッシュしているということですか? (?)

これを解決する方法はありますか?

マイスタック:

Safari: Version 10.0.1 (12602.2.14.0.7) macOS: 10.12.1 (16B2657) host: localhost protocols: tested on both, http and https

さらに詳しい情報:

  • イベントpageshowは常にfalseに設定されpersisted性質を持っています。したがって、Safariによるページキャッシュ(BFCache)は問題の原因ではないはずです。
+0

悪意のあるサイトでは、タブを閉じる前の「確認」が一般的であるため、おそらくマルウェア対策の保護に惑わされている可能性があります。 – ssube

+0

@ssube Safariは私の繰り返しの確認の試みをマルウェアの動作として解釈するので、自分のロジックを無視するだけです。 - ChromeとFirefoxは、ユーザーが決定するためのチェックボックスを確認ポップアップに追加します。_ "このページが追加のダイアログを作成しないようにする" _、もちろん完全に賢明です。 - Safariはそのようなオプションを提供していないのですか? – juanmirocks

+0

Safariの動作が不明ですが、同様の機能がコードを破損する可能性があるようです。あなたがページを繰り返し開いてダイアログを開いてユーザーが退出するのを見たことがあるならば、ほとんどのブラウザーはそれに対して何らかの防御を持っています。 ChromeとFFでうまくいけば、Safariが不気味なことをするチャンスがあります。 – ssube

答えて

1

Safariのバック/フォワードキャッシュの問題と思われます。このキャッシュ(BFCacheまたはページキャッシュとも呼ばれます)は、JavaScriptコード状態を含むWebページ全体の現在の状態を保存し、ユーザーがブラウザの「戻る」ボタンを押すとそれを復元します。あなたはそれについてhereを読むことができます。通常、ロードされたWebページブラウザでbeforeunloadが使用されると、BFCacheはオフになります。しかし、あなたのJavaScriptコードには、この動作を止める何かがあるかもしれません。あるいは、unSaved state = falseと設定してキャッシュに入れますか?手動で試してみてください、あなたのページに回避策を追加することによって、戻る/進むキャッシュをオフにします。

window.onpageshow = function(event) { 
    if (event.persisted) { 
     window.location.reload() 
    } 
}; 
+0

ありがとうございます@ Sergey。あなたの答えと追加の解決策は、おそらく私の問題を解決するでしょう!私は後で報告する。 – juanmirocks

+0

ありがとうございました。残念ながら、これは私の問題を解決しませんでした。参照:http://stackoverflow.com/questions/40727989/is-onbeforeunload-cached-on-safari-macos#comment69049563_40896361 - その他のアイデアはありますか?ありがとう:) – juanmirocks

2

問題

あなたの問題はバックフォワードキャッシュ(BFCache)と呼ばれるブラウザの機能によって引き起こされます。

ユーザーがナビゲートするとページの完全な状態を保存することになっています。このアイデアは、ユーザーが戻るボタンページを使って戻るときに、キャッシュから非常に迅速にロードできるということです。

ChromeとFirefoxは、beforeunloadのイベントハンドラを、バックフォワードキャッシュにページを保存しないというシグナルとして認識しますが、Safariはそのようなハンドラを無視します。


ソリューション

私は唯一の1ワーキングソリューションを発見したが、それは少し、不完全なハック醜いです。

onpageshowイベントの永続プロパティを確認できます。初期ページの読み込み時にfalseに設定されます。 back-forward cacheからページがロードされると、trueに設定されます。

onpageshowイベントは、onloadイベントに似ていますが、ページが最初にロードされるときにonloadイベントが発生した後に発生する点が異なります。また、onpageshowイベントは、ページがロードされるたびに発生し、onloadイベントは、ページがキャッシュからロードされたときには発生しません。

に注意することが重要

をページがまだリロードする前に簡単に示されているように、溶液はかなり不完全です。これは、ページが読み込まれた後に再び開始されることを意味します。結局のところ、ページが完全にロードされた後にリロードを引き起こすようなものではありません。

もう少し小さなことがあります:もちろん、ソリューションはjavascriptを無効にすることで簡単にバイパスされます。このquestion

window.onpageshow = function(event) { 
    if (event.persisted) { 
     window.location.reload(); 
    } 
}; 

クレジットSafari Page Cachepossible future changes to how unload events work
  • ミカTuupolaのanswerについて
    • 情報:

    ので、ご自身の責任でそれを使用します

    +0

    非常にありがとう@Kaloyan。私は今日、このソリューションを試して報告します。あなたに恩恵を与える可能性があります:-) – juanmirocks

    +1

    ありがとう@juanmirocks、私はそれを感謝します:-) –

    +0

    ありがとう、もう一度。あなたの答えは非常に明確で非常に有益でした(奨励金!)。 **非常に残念なことに**、提案されたソリューションを試した後、私はSafariで以前の同じ動作を経験します。私は 'http'と' https'の両方でテストしました。さらに詳しい情報として、イベント 'pageshow'は常に' persisted''を 'false'に設定しています。実際、私はバック/フォワードボタンをまったく使用していません。むしろ、私は通常のページリンクでページ間を移動します。だから私は知らない... ---あなたが他の仮説を思いつくことができれば本当に感謝:) – juanmirocks

    関連する問題