web-dev-qa-db-ja.com

起動されないイベントをナビゲート/アンロードするときのiOS5Safariのページキャッシュの問題

tl; dr-iOS 5のSafariは非常にハードにキャッシュしているので、私のサイトを壊しています。

IOS5のSafariブラウザが「ページキャッシュ」と呼ばれるバックフォワードキャッシュを処理する方法に苦労しています。それが説明されている方法 ここ は動作を非常によく説明しています。

簡単に言うと、ページキャッシュを使用すると、ページを離れるときに「一時停止」し、戻ってきたときに「再生」を押します。

これは私のサイト全体で問題を引き起こしています。戻るボタンを使用すると、他のほとんどのブラウザでは、ページが読み込まれた状態で表示されます。 iOS 5のSafariではなく、最後にページを離れたときのページが表示されます。簡単な例は、送信ボタンを無効にすることです。 Javascriptを使用して送信ボタンを無効にした場合、フォームを送信します。もう一度クリックすると、送信ボタンは無効のままになります。これは、デスクトップバージョンのSafariを含む他のブラウザで問題になっていますが、onloadイベントハンドラを空白の関数に設定することで解決されます。その関数で何か重要なことが起こった可能性があるため、これはブラウザにキャッシュを無効にするように指示していると思います。このハックは、iOS5のSafariでは機能しないようです。

以下は、必要不可欠なものに要約された問題です。 test.htmlをロードすると、「元のテキスト」というテキストが表示されます。リンクをクリックすると、そのテキストは「変更されたテキスト-次のページに転送」に変わり、3秒後にtest2.htmlに転送されます。これまでのところ、すべてのブラウザで問題はありません。他のすべてのブラウザでは、戻るボタンをクリックすると表示されるテキストは「元のテキスト」ですが、iOS 5用のSafariでは、「変更されたテキスト-次のページに転送」と表示されます。

これに対処する方法について何か提案はありますか?

これは簡単な例です

test.html

<script>
function changeText() {
    el = document.getElementById("text");
    el.innerHTML = "Changed text - forwarding to next page";
    setTimeout("forward()",3000);       
}
function forward() {
    document.location.href = "test2.html";
}
</script>
<div id="text">Original Text</div>
<a href="Javascript:changeText()">Click Here</a>
<script>
window.onunload = function(){};
</script>

test2.html

<div>Click back button</div>

これはフォームポストを使用した2番目の例です。これは私のアプリがどのように機能しているかの簡単な例です。 formtest2.aspに戻ると、投稿されたフォーム値が表示され、divテキストはオリジナルである必要があります。

formtest.asp

<form method="post" action="formtest2.asp">
    Test: <input type="text" name="test"/>
    <input type="submit" value="Submit"/>
</form>

formtest2.asp

<script>
function changeText() {
    el = document.getElementById("text");
    el.innerHTML = "Changed text - forwarding to next page";
    setTimeout("forward()",3000);       
}
function forward() {
    document.location.href = "test2.html";
}
</script>

<%
Dim test
test = Request("test")
Response.Write("Test value: " & test & "<br />")
%>

<div id="text">Original Text</div>
<a href="Javascript:changeText()">Click Here</a>
<script>
window.onunload = function(){};
</script>

test2.html

<div>Click back button</div>
18
Clarke

私も同じ問題に対する答えを探していました。 iOS 5に戻ると、JavaScriptは実行されず、ページを離れたときまたはリダイレクトされたときの前の状態のままになります。

戻るボタンをクリックしたときにクロスブラウザのonloadイベントはありますか? 」で見つかった奇妙な「onunload」ハックを試してみると、iOS 4でのみ機能し、期待どおりにイベントを呼び出さないiOS5では機能しませんでした。 Nickolayは、Giuseppeの例よりもはるかに信頼性の高い、「pageshow」および「pagehide」と呼ばれるWebキットの新機能を指摘しました。

  1. この記事のハックが必要です: " 戻るボタンをクリックしたときにクロスブラウザのonloadイベントはありますか? "これをiOS4で機能させるには。
  2. 新しいイベントを使用して、ページがキャッシュからロードされたかどうかを安全にチェックし、iOS 5のリロードを強制する(URLチェックとローカルストレージを回避し、iPodも含む)このスクリプトを使用します。

    <body onunload="">
    ...
    <script type="text/javascript">
    if ((/iphone|iPod|ipad.*os 5/gi).test(navigator.appVersion)) {
      window.onpageshow = function(evt) {
        // If persisted then it is in the page cache, force a reload of the page.
        if (evt.persisted) {
          document.body.style.display = "none";
          location.reload();
        }
      };
    }
    </script>
    
26
BrutalDev

私のモバイルサイトでは、この小さなJSコードの問題を修正しました。

if ((/iphone|ipad.*os 5/i).test(navigator.appVersion)) {
    window.onload=function () {
        localStorage.setItem("href",location.href);
    };
    window.onpopstate=function () {
        var a=localStorage.getItem("href"),
            b=location.href;
        if (b!==a&&b.indexOf((a+"#"))===-1) {
            document.body.style.display="none";
            location.reload();
        }
    };
}

シナリオ:

「Page1」から「Page2」へのリンクをクリック:「Page1」をクリックすると、「Page2」が読み込まれ、onloadやその他の多くのイベントが発生します。

[Page1]->リンクをクリック-> [Page2]-> onload-> onpopstate->.。

この時点でブラウザの戻るボタンをクリックすると、「Page2」が閉じられ、「Page1」が読み込まれ、onloadやその他の多くのイベントが発生します。

[Page2]->戻るボタンをクリック-> [Page1]-> onload-> onpopstate->.。

IOS5で戻るボタンをクリックすると、「Page1」が閉じ、「Page2」が表示されますが、ページがロードされず、ビューポートスケールが破損し、発生するイベントはonpopstateのみです。

[Page2]->戻るボタンをクリック-> [Page1]-> onpopstate。

修正:

この修正は、イベントonload、onpopstate、およびlocalStorageオブジェクトを回避します。

onloadは、スクリプトによって管理される最初のイベントであり、その中で現在のlocation.hrefをlocalStorageに保存します。

バグがない場合、onpopstateでは、現在のlocation.hrefと保存されているhrefが同じである必要があり、スクリプトは何もしません。

IOS5でSafariを使用すると、ページが読み込まれず、onloadイベントが発生しません。その場合、location.hrefと保存されているhrefはonpopstateイベントで異なります。

この場合、現在のページを非表示にして(これに関連するビューポートの別のバグのために)、ロケーションオブジェクトを使用してページを再読み込みします。

私は同じ問題に直面しています。
iOS4で、homepage.htmlを2.htmlに移動してからhomepage.htmlに戻ると、js しないが呼び出されます。 homepage.htmlから2.htmlに移動すると、2.htmlから3.htmlに移動し、3から2に戻ってホームページに戻ると、JS 予定が呼び出されます。はい、それはひどいです!
しかし、iOS5 MobileSafariでは、常に呼び出すことはできません:(これはiOS5のキャッシュバグかもしれません。iOS5.0.0と5.0.1でテストしたところ、同じ結果が得られました。

ただし、body要素にonUnloadイベントを実装すると、以前のMobileSafariでのバックフォワードの問題を修正できます。ホームページ.htmlで_<body>_を_<body onUnload="">_に変更し、ホームページから2.htmlに変更しただけで、ホームページに戻ると、ホームページのJavaScriptが呼び出されます。 FF、デスクトップSafari、モバイルSafariで動作します(iOS4

では、iOS5でどのようにできるでしょうか?残念ながら、私は解決策を見つけられませんでした。しかし、私のwebappはネイティブクライアントで実行されます。ネイティブからのreload()呼び出しを追加することで、これを修正しました。

 if(isOS5 _)
 {
 [webView stringByEvaluatingJavaScriptFromString:@ "location.reload();"]; 
} 

_webViewDidFinishLoad:_のとき

1
Elf Sundae

私たち全員がこれに関して抱えていると思われる問題の1つを回避する方法を見つけた後、私は共有したいと思います:)

主にスタックオーバーフローの「最もホットなサブジェクト」に関する主題に関するいくつかの関連トピックを読んだ後、「ページキャッシュ」を処理します( http://www.webkit.org/blog/427/webkit-page-cache-i -the-basics / および http://www.webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/ )、「unload "イベント(developer.Apple.com/library/IOS/ipad/#documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html)/" pageshow "は、以前の状態の短い"ページの出現 "を処理する必要はありません。 (前のページの初期状態ではなく、残されたページのみ)ユーザーがアプリに戻る/またはデバイスのロックを解除する/または終了後にアプリに戻る。

(少なくとも私にとっては)この「目に見えるページの不具合」は、5分前のようにIOS6のアップデートを行ったときに解決されたようです; D

その後、モバイルサファリで通常どおりWebアプリを使用でき、ホーム画面に追加した後、キャッシュがクリアされているかどうかに関係なく、「アプリの切り替え」または「再起動」の場合の動作は最初の起動と同じです。 :空白のページが表示され、次にコンテンツが表示されます(ホーム画面に保存されたURLに対応するページ、またはlocalStorageを使用して読み込まれたその他のコンテンツ([my case(..)]など))。

私がキャッチできたイベントについても、IOS4 IOS5デバイスでは、その「視覚的持続性の不具合」をなんとか取り除くことができませんでした。これは「ページキャッシュ」の仕組みによるものだと思いますが、iPadでIOS6を実行しています。グリッチがなくなったので、Safariチームは「ホーム画面」のWebアプリの処理方法を改善したに違いありません(.. )

0
StephaneAG