ホームページ > 記事 > ウェブフロントエンド > JavaScript クロスドメインの概要と解決策
クロスドメインとは何ですか?
セキュリティ上の理由から、JavaScript では他のページ上のオブジェクトへのクロスドメイン呼び出しは許可されていません。ただし、セキュリティ上の制限に加えて、iframe または ajax アプリケーションの挿入には多くの問題が発生します。ここでは、クロスドメインに関連するいくつかの問題の簡単な概要を示します:
まず第一に、クロスドメインとは何ですか? 簡単に理解すると、JavaScript の同一オリジン ポリシーの制限により、js がドメイン名 a の下にあることになります。 com は、ドメイン名の下で b.com または c.a.com オブジェクトを操作できません。詳細な手順については、以下の表を参照してください。
URL 説明 通信が許可されるかどうか
http://www.a.com/a.js
http://www.a.com/b.jsドメイン名、許可されます
http://www.a.com/lab/a.js
http://www.a.com/script/b.js 同じドメイン名の下にある異なるフォルダーは許可されます
http:// www.a.com:8000/ a.js
http://www.a.com/b.js 同じドメイン名、異なるポートは許可されません
http://www.a.com/a.js
https ://www.a.com/b .js 同じドメイン名、異なるプロトコルは許可されません
http://www.a.com/a.js
http://70.32.92.74/b.js ドメイン名とドメイン名に対応するIPは許可されません
http://www.a.com/a.js
http://script.a.com/b.js メインドメインは同じですが、サブドメインが異なります。
http://www.a.com/a.js
http://a.com/b.js 同じドメイン名、異なる第 2 レベル ドメイン名 (上記と同じ) は許可されません (Cookie は許可されません) )
http://www.cnblogs.com/a.js
http://www.a .com/b.js 異なるドメイン名は許可されません
次の 2 つの点に特に注意してください:
第一に、クロスドメインの問題がプロトコルやポートによって引き起こされている場合、「フロントデスク」は無力です
第二に、クロスドメインの問題については、ドメインが単に「URLヘッダー」によって識別されるかどうかを判断しようとせず、同じ IP アドレスが 2 つのドメインに対応するか、または 2 つのドメインが同じ IP 上にあるかどうか。
「URL ヘッダー」は window.location.protocol +window.location.host を指します。これは、「ドメイン、プロトコル、ポートが一致する必要がある」とも解釈できます。
以下は、「フロントエンド」でクロスドメインを処理する一般的な方法の簡単な概要です。バックエンド プロキシ ソリューションにはバックエンド構成が含まれますが、ここでは説明しません。 Yahoo のこの記事を読んでください: 「JavaScript: クロスドメイン XMLHttpRequest 呼び出しに Web プロキシを使用する」
1. document.domain+iframe の設定
メイン ドメインが同じでサブドメインが異なる例としては、次のようになります。 document.domain を設定することで解決しました。具体的な方法は、 http://www.a.com/a.html と http://script.a.com/b.html の 2 つのファイルに document.domain = 'a.com' をそれぞれ追加して、 a.html ファイル内の iframe は、iframe の contentDocument を制御し、2 つの js ファイルが「相互作用」できるようにします。もちろん、この方法で解決できるのは、プライマリ ドメインは同じでセカンダリ ドメイン名が異なる場合のみです。いきなり script.a.com のドメインを alibaba.com に設定すると、当然エラーになります。報告!コードは次のとおりです:
a.html on www.a.com
document.domain = 'a.com';
var ifr = document.createElement('iframe');
ifr.src = 'http: // script.a.com/b.html';
ifr.style.display = 'none';
document.body.appendChild(ifr);
ifr.onload = function(){
var doc = ifr.contentDocument || ifr.contentWindow.document;
// ここで b.html を操作します
alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue);
};
b script.a.com .html
document.domain = 'a.com';
このメソッドは、{www.kuqin.com、kuqin.com、script.kuqin.com、css.kuqin.com} のどのページでも通信できるようにするのに適しています。他の。
注: 特定のページのドメインは、デフォルトでは window.location.hostname と等しくなります。メイン ドメイン名は、www のないドメイン名 (a.com など) です。通常、先頭にプレフィックスが付いているメイン ドメイン名は、www.a などの第 2 レベル ドメイン名またはマルチレベル ドメイン名です。 .com は実際には第 2 レベルのドメイン名です。ドメインはプライマリ ドメイン名としてのみ設定でき、ドメインを b.a.com 内の c.a.com に設定することはできません。
問題:
1. セキュリティ: 1 つのサイト (b.a.com) が攻撃されると、別のサイト (c.a.com) がセキュリティ上の脆弱性を引き起こします。
2. ページに複数の iframe を導入する場合、すべての iframe を操作できるようにするために同じドメインを設定する必要があります。
2. スクリプトを動的に作成する
ブラウザはデフォルトでクロスドメインアクセスを禁止していますが、ページ内の他のドメインからのJSファイルの参照は禁止しておらず、導入したJSファイル内の機能(Cookieの操作やDomの操作を含む)を自由に実行できます。 、など)。これに基づいて、スクリプト ノードを作成することで、完全なクロスドメイン通信を簡単に実現できます。具体的な方法については、YUI の Get Utility を参照してください
スクリプト ノードが読み込まれているかどうかを判断するのは非常に興味深いものです。IE はスクリプトのreadystatechange 属性のみを使用でき、他のブラウザはスクリプトのloadイベントを使用します。スクリプトがロードされているかどうかを確認する方法をいくつか次に示します。
js.onload = js.onreadystatechange = function() {
if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {
// ここでコールバックを実行どこでも
js.onload = js.onreadystatechange = null;
}
}; 3. iframe と location.hash を使用します
この方法はより複雑ですが、完全にクロスドメインの状況での足跡の置換の問題を解決できます。原則として、location.hash を使用して値を転送します。 URL: http://a.com#helloword では、「#helloworld」は location.hash です。ハッシュを変更してもページは更新されないため、データの転送にはハッシュ値を使用できます。容量は限られています。ドメイン名 a.com のファイル cs1.html が、ドメイン名 cnblogs.com の cs2.html に情報を転送する必要があるとします。cs1.html は、iframe の src を指すように自動的に作成されます。ドメイン名 cnblogs.com の cs2.html ページでは、このときのハッシュ値をパラメータの受け渡しに使用できます。 cs2.html がリクエストに応答した後、cs1.html のハッシュ値を変更してデータを渡します (2 つのページは同じドメイン内にないため、IE と Chrome ではparent.location の値の変更は許可されません)。ハッシュなので、.com ドメイン名のプロキシ iframe を使用する必要があります。Firefox はそれを変更できます。同時に、cs1.html にタイマーを追加して、一定期間後に location.hash の値が変化したかどうかを確認し、変化がある場合はハッシュ値を取得します。コードは次のとおりです:
var ifr = document.createElement('iframe');
ifr.style.display = 'none ';
ifr .src = 'http://www.cnblogs.com/lab/cscript/cs2.html#paramdo';
document.body.appendChild(ifr);
}
try {var data = location.hash.hash.substring(1): ''; (checkHash、2000);cnblogs.com ドメイン名の下の
cs2.html:
//単純なパラメーター処理操作をシミュレートします
switch(location.hash){
case '#paramdo':
callBack ();
Break ; e) {
// IE、Chrome のセキュリティ メカニズムは Parent.Location.hash を変更できません。
// したがって、エージェント Iframe を使用します
}
}
a.com ドメイン名 cs3.html
//parent.parent とそれ自体は同じドメインに属しているため、その location.hash の値を変更できます
parent .parent.location.hash = self.location.hash.substring(1);
もちろん、これを行うには、データが URL で直接公開される、データの容量とタイプが制限されるなど、多くの欠点があります。 ...
4. Window.name の実装 クロスドメイン データ転送
5. HTML5 postMessage を使用する
HTML5 の最も優れた新機能の 1 つは、クロス ドキュメント メッセージングです。次世代のブラウザでは、Chrome 2.0 以降、Internet Explorer 8.0 以降、Firefox 3.0 以降、Opera 9.6 以降、および Safari 4.0 以降がこの機能をサポートします。 Facebook はすでにこの機能を使用して、postMessage によるリアルタイムの Web ベースのメッセージングをサポートしています。
otherWindow.postMessage(message, targetOrigin);
otherWindow: メッセージ ページを受信するウィンドウへの参照。ページ内の iframe の contentWindow 属性、window.open の戻り値、または名前または添字を通じて window.frames から取得した値にすることができます。
メッセージ: 送信されるデータ、文字列タイプ。
targetOrigin: otherWindow を制限するために使用されます。「*」は制限がないことを意味します
a.com/index.html のコード:
htmlのbb.com/index。 ) {
alert (event.data); // 「私はそこにいました!」
}、false)
& lt;/script & gt; メッセージ メカニズム、https://developer.mozilla.org/en/dom/window.postmessage
6.これは、YUI3 の IO コンポーネントで見られるメソッドです。詳細については、http://developer.yahoo.com/yui/3/io/ を参照してください。
クロスドメイン プロキシ ファイル仕様の詳細については、Adobe Developer Connection で確認できます: ross-Domain ポリシー ファイル仕様、HTTP ヘッダー ブラックリスト