web-dev-qa-db-ja.com

オンライン/オフラインWebアプリのHTML5キャッシュマニフェストを適切に無効にする方法

現在、キャッシュマニフェストを使用しています( here で説明)。これにより、ユーザーがオフラインのときにアプリケーションを実行するために必要なリソースを効率的に利用できます。

残念ながら、少しうまく機能します。

キャッシュマニフェストが読み込まれると、Firefox 3.5以降は、キャッシュマニフェストで明示的に参照されるすべてのリソースをキャッシュします。ただし、サーバー上のファイルが更新され、ユーザーがオンラインでページを強制的に更新しようとすると(キャッシュマニフェスト自体を含む)、Firefoxは絶対にフェッチを拒否します。アプリケーションは、最後にキャッシュされた時点で完全にフリーズしたままです。質問:

  1. ネットワーク接続が失敗した場合にのみ、Firefoxがキャッシュされたリソースに効果的に依存するようにします。 FALLBACKブロックを使用してみましたが、役に立ちませんでした。これも可能ですか?
  2. #1が不可能な場合、ユーザーがページを強制的に更新してこのキャッシュをバイパスすることは可能ですか?あるいは、キャッシュマニフェストメカニズムは有効期限ヘッダーをサポートしており、これに関する動作はどこにでも文書化されていますか?
53
Justin Searls

私はこれを理解したと思います:キャッシュマニフェストにエラーがある場合(たとえば、参照ファイルが存在しない場合)、FirefoxはapplicationCache関連の処理を完全に停止します。つまり、キャッシュされたキャッシュマニフェストを含め、キャッシュ内の何も更新されません。

これが問題であることを明らかにするために、私は Mozillaからいくつかのコードを借りました をアプリケーションの新しい(キャッシュされていない)HTMLファイルに落としました。ログに記録された最後のメッセージには、キャッシュマニフェストに問題がある可能性があり、十分に問題がある(ファイルが欠落している)可能性があることが示されました。


// Convenience array of status values
var cacheStatusValues = [];
 cacheStatusValues[0] = 'uncached';
 cacheStatusValues[1] = 'idle';
 cacheStatusValues[2] = 'checking';
 cacheStatusValues[3] = 'downloading';
 cacheStatusValues[4] = 'updateready';
 cacheStatusValues[5] = 'obsolete';

 // Listeners for all possible events
 var cache = window.applicationCache;
 cache.addEventListener('cached', logEvent, false);
 cache.addEventListener('checking', logEvent, false);
 cache.addEventListener('downloading', logEvent, false);
 cache.addEventListener('error', logEvent, false);
 cache.addEventListener('noupdate', logEvent, false);
 cache.addEventListener('obsolete', logEvent, false);
 cache.addEventListener('progress', logEvent, false);
 cache.addEventListener('updateready', logEvent, false);

 // Log every event to the console
 function logEvent(e) {
     var online, status, type, message;
     online = (isOnline()) ? 'yes' : 'no';
     status = cacheStatusValues[cache.status];
     type = e.type;
     message = 'online: ' + online;
     message+= ', event: ' + type;
     message+= ', status: ' + status;
     if (type == 'error' && navigator.onLine) {
         message+= ' There was an unknown error, check your Cache Manifest.';
     }
     log('
'+message); } function log(s) { alert(s); } function isOnline() { return navigator.onLine; } if (!$('html').attr('manifest')) { log('No Cache Manifest listed on the tag.') } // Swap in newly download files when update is ready cache.addEventListener('updateready', function(e){ // Don't perform "swap" if this is the first cache if (cacheStatusValues[cache.status] != 'idle') { cache.swapCache(); log('Swapped/updated the Cache Manifest.'); } } , false); // These two functions check for updates to the manifest file function checkForUpdates(){ cache.update(); } function autoCheckForUpdates(){ setInterval(function(){cache.update()}, 10000); } return { isOnline: isOnline, checkForUpdates: checkForUpdates, autoCheckForUpdates: autoCheckForUpdates }

これは確かに役に立ちましたが、少なくともエラーコンソールに不正なキャッシュマニフェストを出力する機能をMozillaに間違いなく要求する必要があります。名前を変更したファイルのように些細な問題を診断するために、これらのイベントにアタッチするカスタムコードは必要ありません。

25
Justin Searls

HTML5 Rocks:キャッシュを更新する :のコードを使用しました

window.addEventListener('load', function(e) {
  if (window.applicationCache) {
    window.applicationCache.addEventListener('updateready', function(e) {
        if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
          // Browser downloaded a new app cache.
          // Swap it in and reload the page to get the new hotness.
          window.applicationCache.swapCache();
          if (confirm('A new version of this site is available. Load it?')) {
            window.location.reload();
          }
        } else {
          // Manifest didn't changed. Nothing new to server.
        }
    }, false);
  }
}, false);
15
Danubian Sailor

私は同じ問題を抱えていました。Firefoxがオフラインファイルを保存すると、それらはリロードされません。 Chromeは期待どおりに動作し、マニフェストファイルの変更をチェックし、マニフェストファイルが変更された場合はすべてをリロードしました。

調査の結果、Firefoxがキャッシュマニフェストファイル(オフラインキャッシュではなく、旧式のキャッシュ)をキャッシュしていることがわかりました。マニフェストファイルのキャッシュヘッダーをCache-Control: no-cache, privateに設定すると、問題が解決しました。

7
OlliM

免責事項:マニフェストとキャッシュに関する私の経験はすべてSafariであり、FFはいくつかの処理を異なる方法で行う場合があります。

  1. たしかにそれは正しいね。マニフェストに見つからないファイルがリストされている場合、キャッシュは発生しません。

  2. オンラインの場合でも、ブラウザはマニフェストファイルのみをチェックします。マニフェストファイルを待機している間、キャッシュからサイトをロードし続けます(レンダリングを遅らせません)が、最初のロードで変更が表示されないことを意味します。

  3. 次回サイトがロードされるときに、前回のロードでマニフェストが変更された場合、新しいファイルがロードされます。

IT IS変更を確認するには常に2回リロードする必要があります。実際、更新を確認するために3回リロードしなければならないことがあります。理由はわかりません。

デバッグ時には、PHPを使用してその場でマニフェストファイルを生成するため、ファイル名にタイプミスの可能性はありません。また、更新を強制するために毎回バージョン番号をランダムに生成しますが、テスト用のオフラインwebappがあります。

完了すると、phpファイルは保存されたマニフェストデータを一定のバージョン番号でエコーすることができ、キャッシュが常に使用されます。

最近、マニフェストとキャッシュで遊んでいる間に学んだことがいくつかあります。うまく機能しますが、混乱を招く可能性があります。

有効期限はありません。キャッシュを解除するには、マニフェストファイルを変更して、何も含まれていない状態でリロードする必要があります。 Safariでは、ユーザーキャッシュをクリアすると、キャッシュされたすべてのファイルがクリアされます。

7
GeoNomad

キャッシュマニフェストを無効にし、HTML5ローカルストレージをクリアするFirefoxアドオンを作成しました。

http://sites.google.com/site/keigoattic/home/webrelated#TOC-Firefox-HTML5-Offline-Cache-and-Loc

エラーコンソールで以下のコードを入力して、キャッシュマニフェストを無効にすることもできます。

// invalidates the cache manifest
var mani = "http://.../mysite.manifest"; // manifest URL
Components.classes["@mozilla.org/network/application-cache-service;1"].getService(Components.interfaces.nsIApplicationCacheService).getActiveCache(mani).discard();

または、アドレスバーに以下のコードを入力することにより、キャッシュの更新を手動で強制します。

javascript:applicationCache.update()
3
keigoi

うーん、マニフェストファイルに編集変更を加えた後、キャッシュでupdate()を呼び出し、チェック/ダウンロード/準備の完全なシーケンスを受け取り、1回リロードし、jsで行ったテキスト変更を行いましたアプリの最初のページに表示されるファイルがすぐに表示されました。

リロードが1回だけ必要なようです。

2
BobFromBris