FirefoxとSafariがiframeコンテンツをキャッシュしないようにするにはどうすればよいですか?
別のサイトのページへのiframeを持つ単純なWebページがあります。外部ページと内部ページの両方に、キャッシュを防ぐためのHTTP応答ヘッダーがあります。ブラウザの「戻る」ボタンをクリックすると、外側のページは正常に機能しますが、ブラウザは常にiframeされたページのキャッシュを取得します。 IEは問題なく動作しますが、FirefoxとSafariは問題を引き起こしています。
私のウェブページは次のようになります。
_<html>
<head><!-- stuff --></head>
<body>
<!-- stuff -->
<iframe src="webpage2.html?var=xxx" />
<!-- stuff -->
</body>
</html>
_
var
変数は常に変更されます。 iframeのURLが変更されたという事実(したがって、ブラウザーはそのページに対して新しいリクエストを行う必要があります)にもかかわらず、ブラウザーはキャッシュされたコンテンツを取得するだけです。
HTTPリクエストとレスポンスを行き来して調べましたが、外側のページに_<iframe src="webpage2.html?var=222" />
_が含まれていても、ブラウザは_webpage2.html?var=111
_をフェッチし続けることに気付きました。
これまでに試したことは次のとおりです。
同じ起源のポリシーによってブロックされているため、JavaScriptのトリックを実行できません。
アイデアが不足しています。誰かがブラウザがiframeされたコンテンツをキャッシュするのを止める方法を知っていますか?
ダニエルが別のテストを実行するように提案したように、私はFiddler2をインストールしましたが、残念ながら、まだ同じ結果が得られています。
これは私が実行したテストです:
Math.random()
を使用して乱数を生成します。このテストでは、どのページが更新され、どのページがキャッシュされているかを正確に確認できます。
簡単なテストのために、ページをロードし、別のページに移動してから「戻る」を押します。結果は次のとおりです。
元のページ:
ページを離れてから戻る
これは、外部ページがURLの異なるGETパラメーターを使用して呼び出しているにもかかわらず、内部ページがキャッシュされていることを示しています。何らかの理由で、ブラウザはiframeが新しいURLを要求しているという事実を無視しています。古いものを単にロードします。
案の定、フィドラーは同じことを確認します。
(ページをロードします。)
外部ページが呼び出されます。 HTML:
_0.21300034290246206
<iframe src="http://ipv4.fiddler:1416/page1.aspx?var=0.21300034290246206" />
_
http://ipv4.fiddler:1416/page1.aspx?var = 0.21300034290246206 が呼び出されます。
(私はページから離れてナビゲートし、次に戻ります。)
外部ページが呼び出されます。 HTML:
_0.4470929019483644
<iframe src="http://ipv4.fiddler:1416/page1.aspx?var=0.4470929019483644" />
_
http://ipv4.fiddler:1416/page1.aspx?var = 0.21300034290246206 が呼び出されます。
このテストから、Webブラウザーはページをキャッシュしていないように見えますが、iframeのURLをキャッシュしてから、そのキャッシュされたURLで新しいリクエストを作成しています。ただし、この問題を解決する方法についてはまだ困惑しています。
Webブラウザーがiframe URLをキャッシュしないようにする方法についてのアイデアはありますか?
IframeのURLが、iframeの実際のコンテンツを取得して返すプロキシとして機能するサイトのページを指すようにします。これで、同一生成元ポリシーに拘束されなくなりました(編集:iframeキャッシュの問題を防止しません)。
これはFirefoxのバグです。
https://bugzilla.mozilla.org/show_bug.cgi?id=356558
この回避策を試してください。
<iframe src="webpage2.html?var=xxx" id="theframe"></iframe>
<script>
var _theframe = document.getElementById("theframe");
_theframe.contentWindow.location.href = _theframe.src;
</script>
Iframeに一意のname
属性を設定することで、このバグを回避できました-何らかの理由で、これはキャッシュを無効にするようです。 name
属性として動的データを使用するか、使用しているテンプレート言語の現在のmsまたはns時間を使用できます。これは、JSを直接必要としないため、上記のソリューションよりも優れたソリューションです。
私の特定のケースでは、iframeはJSを介して構築されています(ただし、PHP、Rubyなどを使用して同じことを行うことができます)ので、単にDate.now()
を使用します。
return '<iframe src="' + src + '" name="' + Date.now() + '" />';
これにより、テストのバグが修正されます。おそらくwindow.name
内側のウィンドウの変更。
あなたが言ったように、ここでの問題はiframeコンテンツのキャッシングではなく、iframe urlキャッシング。
2018年9月現在、この問題はChromeで発生していますが、Firefoxでは発生していません。
私は多くのことを試しました(GETパラメーターの変更の追加、onbeforeunloadでのiframe urlのクリア、Cookieを使用した「キャッシュからの再読み込み」の検出、さまざまな応答ヘッダーの設定)。
1-簡単な方法:javascriptからiframeを動的に作成する
例えば:
const iframe = document.createElement('iframe')
iframe.id = ...
...
iframe.src = myIFrameUrl
document.body.appendChild(iframe)
2-複雑な方法
here で説明したように、サーバー側では、iframeに提供するコンテンツのコンテンツキャッシュを無効にします[〜#〜] or [〜#〜]親ページの場合(どちらでもかまいません)。
そして
次のように、追加の検索パラメーターを変更して、JavaScriptからiframeのURLを設定します。
const url = myIFrameUrl + '?timestamp=' + new Date().getTime()
document.getElementById('my-iframe-id').src = url
(簡易バージョン、他の検索パラメーターに注意)
これはFirefox 3.5のバグです。
他のすべて(iframeコンテンツにプロキシを使用することを除く)を試した後、同じドメインからのiframeコンテンツのキャッシュを防ぐ方法を見つけました:
_.htaccess
_と書き換えルールを使用して、iframe src
属性を変更します。
RewriteRule test/([0-9]+)/([a-zA-Z0-9]+).html$ /test/index.php?idEntity=$1&token=$2 [QSA]
私がこれを使用する方法は、iframeのURLが次のように見えることです:_example.com/test/54/e3116491e90e05700880bf8b269a8cc7.html
_
[トークン]はランダムに生成された値です。トークンが同じになることはないため、このURLはiframeキャッシュを防ぎます。iframeは、1回の更新でまったく異なるURLをロードするため、まったく異なるWebページであると見なします。
_example.com/test/54/e3116491e90e05700880bf8b269a8cc7.html
_
_example.com/test/54/d2cc21be7cdcb5a1f989272706de1913.html
_
どちらも同じページにつながります。
_$_SERVER["QUERY_STRING"]
_ で非表示のURLパラメーターにアクセスできます
Iframeに常に新しいコンテンツをロードさせるには、GETパラメーターの最後に現在のUnixタイムスタンプを追加します。ブラウザはそれを「異なる」リクエストと見なし、新しいコンテンツを探します。
Javascriptでは、次のようになります。
frames['my_iframe'].location.href='load_iframe_content.php?group_ID=' + group_ID + '×tamp=' + timestamp;
後でアプリでiframe src属性を設定します。アプリケーションの開始時にiframe内のキャッシュされたコンテンツを取り除くには、次のようにします。
myIframe.src = "";
... jsコードの先頭のどこか(たとえばjquery $()ハンドラー)
http://www.freshsupercool.com/2008/07/10/firefox-caching-iframe-data/ に感謝
この問題は、最新のChromeおよび2016年3月17日のMac OS Xの最新のSafariで見つかりました。srcを空に割り当てたり、次に、サイトに戻るか、ランダムな名前の「name」パラメーターを追加するか、ハッシュの後にURLの最後に乱数を追加するか、srcを割り当てた後にコンテンツウィンドウhrefをsrcに割り当てます。
私の場合は、Javascriptを使用してIFRAMEを更新し、URLのハッシュのみを切り替えていたためです。
私の場合の回避策は、他のページへのメタリダイレクトが0秒の暫定URLを作成したことです。それは非常に速く起こるので、画面のフラッシュにほとんど気付きません。さらに、暫定ページの背景色を他のページと同じにしたので、気づかないでしょう。
また、2016年にiOS Safariでこの問題が発生しました。私のために働くように思われたのは、iframe srcにGETパラメータを与え、このような値を与えたことでした<iframe width="60%" src="../other/url?cachebust=1" allowfullscreen></iframe>