web-dev-qa-db-ja.com

ブラウザでのiframeキャッシュの防止

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_をフェッチし続けることに気付きました。

これまでに試したことは次のとおりです。

  • ランダムなvar値でiframe URLを変更する
  • Expires、Cache-Control、およびPragmaヘッダーを外部Webページに追加する
  • Expires、Cache-Control、およびPragmaヘッダーを内部Webページに追加する

同じ起源のポリシーによってブロックされているため、JavaScriptのトリックを実行できません。

アイデアが不足しています。誰かがブラウザがiframeされたコンテンツをキャッシュするのを止める方法を知っていますか?

更新

ダニエルが別のテストを実行するように提案したように、私はFiddler2をインストールしましたが、残念ながら、まだ同じ結果が得られています。

これは私が実行したテストです:

  1. 外部ページは、JSPでMath.random()を使用して乱数を生成します。
  2. 外部ページのWebページに乱数が表示されます。
  3. 外部ページはiframeを呼び出し、乱数を渡します。
  4. 内部ページに乱数が表示されます。

このテストでは、どのページが更新され、どのページがキャッシュされているかを正確に確認できます。

ビジュアルテスト

簡単なテストのために、ページをロードし、別のページに移動してから「戻る」を押します。結果は次のとおりです。

元のページ:

  • 外部ページ:0.21300034290246206
  • 内部ページ:0.21300034290246206

ページを離れてから戻る

  • 外部ページ:0.4470929019483644
  • 内部ページ:0.21300034290246206

これは、外部ページが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をキャッシュしないようにする方法についてのアイデアはありますか?

76
JR.

IframeのURLが、iframeの実際のコンテンツを取得して返すプロキシとして機能するサイトのページを指すようにします。これで、同一生成元ポリシーに拘束されなくなりました(編集:iframeキャッシュの問題を防止しません)。

0
kmoser

これは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>
47
Caleb

Iframeに一意のname属性を設定することで、このバグを回避できました-何らかの理由で、これはキャッシュを無効にするようです。 name属性として動的データを使用するか、使用しているテンプレート言語の現在のmsまたはns時間を使用できます。これは、JSを直接必要としないため、上記のソリューションよりも優れたソリューションです。

私の特定のケースでは、iframeはJSを介して構築されています(ただし、PHP、Rubyなどを使用して同じことを行うことができます)ので、単にDate.now()を使用します。

return '<iframe src="' + src + '" name="' + Date.now() + '" />';

これにより、テストのバグが修正されます。おそらくwindow.name内側のウィンドウの変更。

28
STRML

あなたが言ったように、ここでの問題は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

(簡易バージョン、他の検索パラメーターに注意)

4
steph643

これはFirefox 3.5のバグです。

ご覧ください。 https://bugzilla.mozilla.org/show_bug.cgi?id=279048

3
renga

他のすべて(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パラメーターにアクセスできます

3
Jeff Noel

Iframeに常に新しいコンテンツをロードさせるには、GETパラメーターの最後に現在のUnixタイムスタンプを追加します。ブラウザはそれを「異なる」リクエストと見なし、新しいコンテンツを探します。

Javascriptでは、次のようになります。

frames['my_iframe'].location.href='load_iframe_content.php?group_ID=' + group_ID + '&timestamp=' + timestamp;
3
Division Six

後でアプリでiframe src属性を設定します。アプリケーションの開始時にiframe内のキャッシュされたコンテンツを取り除くには、次のようにします。

myIframe.src = "";

... jsコードの先頭のどこか(たとえばjquery $()ハンドラー)

http://www.freshsupercool.com/2008/07/10/firefox-caching-iframe-data/ に感謝

2
janekw

この問題は、最新のChromeおよび2016年3月17日のMac OS Xの最新のSafariで見つかりました。srcを空に割り当てたり、次に、サイトに戻るか、ランダムな名前の「name」パラメーターを追加するか、ハッシュの後にURLの最後に乱数を追加するか、srcを割り当てた後にコンテンツウィンドウhrefをsrcに割り当てます。

私の場合は、Javascriptを使用してIFRAMEを更新し、URLのハッシュのみを切り替えていたためです。

私の場合の回避策は、他のページへのメタリダイレクトが0秒の暫定URLを作成したことです。それは非常に速く起こるので、画面のフラッシュにほとんど気付きません。さらに、暫定ページの背景色を他のページと同じにしたので、気づかないでしょう。

2
Volomike

また、2016年にiOS Safariでこの問題が発生しました。私のために働くように思われたのは、iframe srcにGETパラメータを与え、このような値を与えたことでした

<iframe width="60%" src="../other/url?cachebust=1" allowfullscreen></iframe>

0