プログラムで作成された<iframe>のドキュメントオブジェクトにアクセスしようとすると、"Access is denied" というJavaScriptエラーが発生する(IEのみ)
質問
JavaScriptを使用して<iframe>要素を作成し、それをDOMに追加する必要があるプロジェクトがあります。その後、いくつかのコンテンツを<iframe>に挿入する必要があります。これは、サードパーティのWebサイトに埋め込まれるウィジェットです。
ページをロードしたくないので、"src" 属性を設定しません。むしろ、親ページと CSS または JavaScript の競合が発生しないように、挿入するコンテンツを分離/サンドボックス化するために使用されます。JSONP を使用して、サーバーから HTML コンテンツを読み込み、この <iframe> に挿入しています。
親ページで document.domain プロパティが設定されている場合 (このウィジェットが配置されている特定の環境ではそうであるかもしれません)、Internet Explorer (おそらくすべてのバージョンですが、6、7、8 で確認しました) では、作成したこの <iframe> のドキュメント オブジェクトにアクセスしようとすると "Access is denied" エラーを表示します。私がテストした他のブラウザ(主要な最新のものすべて)では発生しません。
Internet Explorer では、互いに通信するすべてのウィンドウ/フレームの document.domain を同じ値に設定する必要があることを承知しているので、これはある程度理にかなっています。しかし、アクセスできないドキュメントにこの値を設定する方法については、私は認識していません。
どなたか、これを行う方法、つまり、動的に作成されたこの <iframe> の document.domain プロパティを設定する方法をご存知でしょうか?または、正しい角度から見ていないのでしょうか。この問題に遭遇することなく、私が目指していることを達成する別の方法があるのでしょうか。このウィジェットの機能にとって、隔離されたサンドボックスのウィンドウが重要であるため、いずれにせよ <iframe> を使用する必要があります。
これが私のテストコードです。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Document.domain Test</title>
<script type="text/javascript">
document.domain = 'onespot.com'; // set the page's document.domain
</script>
</head>
<body>
<p>This is a paragraph above the <iframe>.</p>
<div id="placeholder"></div>
<p>This is a paragraph below the <iframe>.</p>
<script type="text/javascript">
var iframe = document.createElement('iframe'), doc; // create <iframe> element
document.getElementById('placeholder').appendChild(iframe); // append <iframe> element to the placeholder element
setTimeout(function() { // set a timeout to give browsers a chance to recognize the <iframe>
doc = iframe.contentWindow || iframe.contentDocument; // get a handle on the <iframe> document
alert(doc);
if (doc.document) { // HEREIN LIES THE PROBLEM
doc = doc.document;
}
doc.body.innerHTML = '<h1>Hello!</h1>'; // add an element
}, 10);
</script>
</body>
</html>
でホストしています。
http://troy.onespot.com/static/access_denied.html
IE でこのページを読み込むとわかりますが、alert() を呼び出した時点で、私は <iframe> のウィンドウ オブジェクトのハンドルを取得しています。
どんなヘルプや提案でも本当にありがとうございます。私は、この解決策を見つけるのを助けることができる人に恩義を感じるでしょう。
どのように解決するのですか?
<ブロッククオート親ページにdocument.domainプロパティが設定されている場合、Internet Explorerで"Access is denied"が表示されます。
はぁー。ええ、IEの問題です(バグ?この種の不愉快なことに関する文書化された標準がないので言いにくい)。srcless iframe を作成すると、そのフレームは
document.domain
を親文書の
location.host
の代わりに
document.domain
. この時点で、あなたはそれを変更することができないので、かなり損をしています。
ひどい回避策は
src
をjavascriptに変換することです。の URL に設定することです (うっ!)。
iframe.src= "javascript:'<html><body><p>Hello<\/p><script>do things;<\/script>'";
しかし、何らかの理由で、このようなドキュメントは、自分自身の
document.domain
をスクリプトから設定することができないので(古き良き "unspecified error")、それを使って親(*)の間のブリッジを取り戻すことはできません。あなたは
ができた
ウィジェットが一度インスタンス化されると、その親ドキュメントと話す必要がないと仮定すると、ドキュメント全体の HTML を書くためにそれを使用することができます。
しかし iframe JavaScript の URL は Safari では動作しないので、使用する方法を選択するために、何らかのブラウザ スニッフィングが必要でしょう。
*: 他の何らかの理由で
できる
を、IE では
document.domain
を、最初のドキュメントによって書かれた第二のドキュメント、document.writtenから設定することができます。だから、これは動作します。
if (isIE)
iframe.src= "javascript:'<script>window.onload=function(){document.write(\\'<script>document.domain=\\\""+document.domain+"\\\";<\\\\/script>\\');document.close();};<\/script>'";
この時点で隠蔽体質が高すぎてアウトです。Davidが言ったように外部HTMLにします。
関連
-
[解決済み] JavaScriptでオブジェクトをディープクローンする最も効率的な方法は何ですか?
-
[解決済み] 私のJavaScriptコードは "No 'Access-Control-Allow-Origin' header is present on requested resource "というエラーを受け取りますが、Postmanはそうならないのはなぜですか?
-
[解決済み] JavaScriptでオブジェクトのキー/プロパティの数を効率的にカウントする方法
-
[解決済み] オブジェクトをメンバーとして、プレーンなJavaScriptオブジェクトをループさせる方法
-
[解決済み] JavaScriptの正規表現でマッチしたグループにアクセスするにはどうすればよいですか?
-
[解決済み] jQueryでJavaScriptオブジェクトから選択する際に、オプションを追加する最も良い方法は何ですか?
-
[解決済み] Javascriptオブジェクトの最初のプロパティにアクセスする方法は?
-
[解決済み] 親ページからiframe内のJavaScriptコードを呼び出す
-
[解決済み] HTML5 CanvasとSVGとdivの比較
-
[解決済み] 変異を伴わないオブジェクトからの値の削除
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 配列からオブジェクトを生成する
-
[解決済み] Chart.jsを使ってドーナツチャートの中にテキストを追加するには?
-
[解決済み] 兄弟ノードを選択する方法はありますか?
-
[解決済み] CORS OriginヘッダーとCSRFトークンによるCSRF保護
-
[解決済み] 無効になっている入力フィールドの値を送信する
-
[解決済み] Javascript 空の配列の削減
-
[解決済み] javascript includes() 大文字小文字を区別しない
-
[解決済み] javascriptで文字列から関数を作成する方法はありますか?
-
[解決済み] JSHintの'+'前の改行不良の説明
-
[解決済み] Fetch: ステータスがOKでない場合、プロミスを拒否し、エラーをキャッチするか?