HTMLページに<iframe>
をロードし、Javascriptを使用してその中の要素にアクセスしようとしましたが、コードを実行しようとすると、次のエラーが発生します。
SecurityError: Blocked a frame with Origin "http://www.<domain>.com" from accessing a cross-Origin frame.
フレーム内の要素にアクセスできるように、解決策を見つけてください。
私はこのコードをテストに使用していますが、無駄です。
$(document).ready(function() {
var iframeWindow = document.getElementById("my-iframe-id").contentWindow;
iframeWindow.addEventListener("load", function() {
var doc = iframe.contentDocument || iframe.contentWindow.document;
var target = doc.getElementById("my-target-id");
target.innerHTML = "Found it!";
});
});
CORS と混同しないでください!
ca n't JavaScriptを使用して異なるOriginで<iframe>
にアクセスすると、できればセキュリティ上の大きな欠陥になります。 same-Origin policyブラウザは、異なるOriginのフレームにアクセスしようとするスクリプトをブロックしますの場合。
住所の次の部分の少なくとも1つが維持されていない場合、起源は異なると見なされます。
<protocol>://<hostname>:<port>/path/to/page.html
Protocol、hostname、およびportは、フレームにアクセスする場合、ドメインと同じでなければなりません。
http://www.example.com/home/index.html
から次のURLにアクセスしようとするとどうなりますか
URL RESULT
http://www.example.com/home/other.html -> Success
http://www.example.com/dir/inner/another.php -> Success
http://www.example.com:80 -> Success (default port for HTTP)
http://www.example.com:2251 -> Failure: different port
http://data.example.com/dir/other.html -> Failure: different hostname
https://www.example.com/home/index.html.html -> Failure: different protocol
ftp://www.example.com:21 -> Failure: different protocol & port
https://google.com/search?q=james+bond -> Failure: different hostname & protocol
Same-Originポリシーは、異なるOriginのサイトのコンテンツへのスクリプトのアクセスをブロックしますが、両方のページを所有している場合、 window.postMessage
とその相対message
イベントを使用してこの問題を回避できます次のように、2つのページ間でメッセージを送信します。
メインページで:
let frame = document.getElementById('your-frame-id');
frame.contentWindow.postMessage(/*any variable or object here*/, '*');
<iframe>
(メインページに含まれています):
window.addEventListener('message', function(event) {
// IMPORTANT: Check the Origin of the data!
if (~event.Origin.indexOf('http://yoursite.com')) {
// The data has been sent from your site
// The data sent with postMessage is stored in event.data
console.log(event.data);
} else {
// The data hasn't been sent from your site!
// Be careful! Do not use it.
return;
}
});
このメソッドは両方向に適用でき、メインページにもリスナーを作成し、フレームから応答を受け取ります。同じロジックをポップアップに実装することもできます。基本的には、メインページで生成される新しいウィンドウ(例: window.open()
を使用)も同様です。
このトピックについては既にいくつかの良い回答があります(グーグルで見つけたばかりです)ので、これが可能なブラウザーについては、相対的な回答をリンクします。ただし、same-Originポリシー(またはCORS)を無効にすると、yourbrowserのみに影響することに注意してください。また、同じ起源のセキュリティ設定を無効にしたブラウザを実行すると、すべてのウェブサイトにクロス起源のリソースへのアクセスが許可されるため、これは非常に安全ではなく、開発目的のみに行う必要があります。
Marco Bonelliの答えを補完する:フレーム/ iframe間でやり取りするための現在の最良の方法は window.postMessage
、 を使用することです - すべてのブラウザでサポートされています - /
ドメインのWebサーバーでhttp://www.<domain>.com
のX-Frame-Options
設定を確認してください。これはclickJacking攻撃を防ぐために設計されたセキュリティ機能です。
技術的には、悪は犠牲者ページへのソースを持つiframe
を持っています。
<html>
<iframe src='victim_domain.com'/>
<input id="username" type="text" style="display: none;/>
<input id="password" type="text" style="display: none;/>
<script>
//some JS code that click jacking the user username and input from inside the iframe...
<script/>
<html>
Webサーバのリクエストがiframe
内にレンダリングされないようにしたい場合は、 x-frame-options を追加します。
XフレームオプションDENY
オプションは以下のとおりです。
これはIIS configの例です。
<httpProtocol>
<customHeaders>
<add name="X-Frame-Options" value="SAMEORIGIN" />
</customHeaders>
</httpProtocol>
Webサーバがセキュリティ機能を有効にした場合、クライアント側のSecurityErrorが発生する可能性があります。
私にとっては、双方向ハンドシェイクを実装したいと思っていました。
- 親ウィンドウはiframeよりも速くロードされます
- 準備ができ次第、iframeは親ウィンドウと対話します
- 親はiframeメッセージを受信して再生する準備ができています
このコードは、 [CSSカスタムプロパティ] を使用してiframeにホワイトラベルを設定するために使用されます。
コード:
iframe
$(function() {
window.onload = function() {
// create listener
function receiveMessage(e) {
document.documentElement.style.setProperty('--header_bg', e.data.wl.header_bg);
document.documentElement.style.setProperty('--header_text', e.data.wl.header_text);
document.documentElement.style.setProperty('--button_bg', e.data.wl.button_bg);
//alert(e.data.data.header_bg);
}
window.addEventListener('message', receiveMessage);
// call parent
parent.postMessage("GetWhiteLabel","*");
}
});
親
$(function() {
// create listener
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
eventer(messageEvent, function (e) {
// replay to child (iframe)
document.getElementById('wrapper-iframe').contentWindow.postMessage(
{
event_id: 'white_label_message',
wl: {
header_bg: $('#Header').css('background-color'),
header_text: $('#Header .HoverMenu a').css('color'),
button_bg: $('#Header .HoverMenu a').css('background-color')
}
},
'*'
);
}, false);
});
当然あなたは起源とテキストを制限することができます、これは働きやすいコードです
この例文は参考になりました。
[postMessageによるクロスドメインメッセージング]