異なるドメインのクロスドメイン テクノロジを説明する前に、以下で説明するテクノロジが異なるサブドメインにわたる以前の状況にも適用できることをまず明確にします。クロスドメインの問題の特殊なケースのみです。もちろん、適切な状況下で適切なテクノロジーを使用すると、より高い効率とより高い安定性を確保できます。 つまり、さまざまなクロスドメイン要件に応じて、クロスドメイン テクノロジは次のカテゴリに分類できます。 1. JSONP クロスドメイン GET リクエスト 2. iframe 3. Flash クロスドメイン HTTP リクエスト 4. window.postMessage 以下では、さまざまなテクノロジーについて詳しく紹介します。 1. JSONP。 ページ内に <script> ノードを作成して異なるドメインに HTTP リクエストを送信する方法は、JSONP と呼ばれます。このテクノロジは、ドメイン間での Ajax リクエストの送信の問題を解決します。 JSONP の動作原理は次のとおりです。 <BR> GET リクエストが http://example1.com/index.php ページ内の http://example2.com/getinfo.php に送信されると仮定すると、次の JavaScript コードを http://example1.com/index.php ページに配置して実装します: </script>
eleScript.src = "http://example2. com/getinfo.php";
document.getElementsByTagName("HEAD")[0].appendChild(eleScript);
当GET请求从http://example2.com/getinfo.php返回时,可以返回一段JavaScript代码,这段代码会自动执行,可以用来负责调用http://example1.com/index.php页面中的一个callback函数。 JSONP的优点是:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果。 JSONP的缺点则是:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
2. 通过iframe实现跨域。 iframe跨域的方式,功能强于JSONP,它不仅能用来跨域完成HTTP请求,还能在前端跨域实现JavaScript调用。因此,完全不同域的跨域问题,通常采用iframe的方式来解决。 与JSONP技术通过创建<script>节点向不同的域提交GET请求的工作方式类似,我们也可以通过在http://example1.com/index.php页面中创建指向http://example2.com/getinfo.php的iframe节点跨域提交GET请求。然而,请求返回的结果无法回调http://example1.com/index.php页面中的callback函数,因为受到“同源策略”的影响。<br><br>为了解决这个问题,我们需要在example1.com下放置一个跨域文件,比如路径是http://example1.com/crossdomain.html。<br><br>当http://example2.com/getinfo.php这个请求返回结果的时候,它大体上有两个选择。<BR>第一个选择是,它可以在iframe中做一个302跳转,跳转到跨域文件http://example1.com/crossdomain.html,同时将返回结果经过URL编码之后作为参数缀在跨域文件URL后面,例如http://example1.com/crossdomain.html?result=<URL-Encoding-Content>。<br><br>另一个选择是,它可以在返回的页面中再嵌入一个iframe,指向跨域文件,同时也是将返回结果经过URL编码之后作为参数缀在跨域文件URL后面。<br><br>在跨域文件中,包含一段JavaScript代码,这段代码完成的功能,是从URL中提取结果参数,经过一定处理后调用原来的http://example1.com/index.php页面中的一个预先约定好的callback函数,同时将结果参数传给这个函数。http://example1.com/index.php页面和跨域文件是在同一个域下的,因此这个函数调用可以通过。跨域文件所在iframe和原来的http://example1.com/index.php页面的关系,在前述第一种选择下,后者是前者的父窗口,在第二种选择下,后者是前者的父窗口的父窗口。<br><br>根据前面的叙述,有了跨域文件之后,我们就可以实现通过iframe方式在不同域之间进行JavaScript调用。这个调用过程可以完全跟HTTP请求无关,例如有些站点可以支持动态地调整在页面中嵌入的第三方iframe的高度,这其实是通过在第三方iframe里面检测自己页面的高度变化,然后通过跨域方式的函数调用将这个变化告知父窗口来完成的。<br><br>既然利用iframe可以实现跨域JavaScript调用,那么跨域提交POST请求等其它类型的HTTP请求就不是难事。例如我们可以跨域调用目标域的JavaScript代码在目标域下提交Ajax请求(GET/POST/etc.),然后将返回的结果再跨域传原来的域。<br><br>使用iframe跨域,优点是功能强大,支持各种浏览器,几乎可以完成任何跨域想做的事情;缺点是实现复杂,要处理很多浏览器兼容问题,并且传输的数据不宜过大,过大了可能会超过浏览器对URL长度的限制,要考虑对数据进行分段传输等。</script>
3. 利用flash实现跨域HTTP请求 据称,flash在浏览器中的普及率高达90%以上。 flash代码和JavaScript代码之间可以互相调用,并且flash的“安全沙箱”机制与JavaScript的安全机制并不尽相同,因此,我们可以利用flash来实现跨域提交HTTP请求(支持GET/POST等)。 例如,我们用浏览器访问http://example1.com/index.php这个页面,在这个页面中引用了http://example2.com/flash.swf这个flash文件,然后在flash代码中向http://example3.com/webservice.php发送HTTP请求。 这个请求能否被成功发送,取决于在example3.com的根路径下是否放置了一个crossdomain.xml以及这个crossdomain.xml的配置如何。flash的“安全沙箱”会保证:仅当example3.com服务器在根路径下确实放置了crossdomain.xml文件并且在这个文件中配置了允许接受来自example2.com的flash的请求时,这个请求才能真正成功。下面是一个crossdomain.xml文件内容的例子:
4. window.postMessage window.postMessage は、HTML 標準の次のバージョンである HTML5 でサポートされる新機能です。現在のインターネット技術の急速な進歩の影響を受けて、ブラウザーのクロスドメイン通信に対する需要はますます高まっており、HTML 標準ではついにクロスドメイン通信が考慮されています。しかし、現時点では HTML5 はまだドラフトにすぎません。 window.postMessage は、直接クロスドメイン通信を実装するための安全な方法です。ただし、現在すべてのブラウザがこの呼び出しをサポートしているわけではありません。Firefox 3、Safari 4、および IE8 のみがこの呼び出しをサポートしています。 他のウィンドウにメッセージを送信するために使用する呼び出しメソッドは、おおよそ次のとおりです。
otherWindow.postMessage(message, targetOrigin);
受信ウィンドウで、送信されたメッセージを受信するイベント処理関数を設定する必要があります。
window.addEventListener("message", acceptMessage, false); function acceptMessage(event) { if (event .origin !== "http://example.org:8080") return; }
メッセージには 3 つの属性が含まれます: data、オリジン (送信ウィンドウが配置されているドメインの実際の情報を運ぶ) とソース (送信ウィンドウのハンドルを表す) です。
セキュリティに関する考慮事項: window.postMessage を使用する場合は、メッセージの送信元属性とソース属性を使用して送信者の身元を確認する必要があります。そうしないと、XSS 脆弱性が発生します。
window.postMessage は、iframe によって実装されたクロスドメイン機能と同じくらい強力で、使いやすく効率的ですが、ブラウザの互換性の点で現時点では改善の必要があるという欠点があります。
原文に追加する必要があるのは、IE6 および IE7 では、オブジェクトまたは関数に割り当てられる IE の Opener の脆弱性が悪用される可能性があり、postMessage ソリューションの補足ソリューションが提供されていることです。
メインページ:
クロスドメイン
< ;/head>
用 iframe 内嵌其它ドメイン下の页面:
& gt;
注: postMessage 方式は現在、さまざまな新しい視聴者からのサポートを、予想外の速度で取得できるようになっており、慎重に検討してください。