JS交差問題の解決策

黄舟
リリース: 2017-03-01 14:31:13
オリジナル
1466 人が閲覧しました

1. 同一オリジンポリシーの制限事項

まず第一に、クロスドメインとは、異なるドメイン間のデータ送信または通信を意味します。 プロトコルドメイン名ポートに違いがある限り、それらは異なるドメインとみなされます。 ドメインを越える場合は、ブラウザの同一生成元ポリシー制限を理解する必要があります。

その制限の 1 つは、ajax を通じてさまざまなソースからドキュメントをリクエスト できないことです。 2 番目の制限は、js がブラウザー内の異なるドメインのフレーム間で相互作用できないことです。 2つ目の制限については、例えばアドレスが http://www.php.cn/ というページがあり、このページ内に iframe があり、その src が http:// www.php.cn/、明らかに、このページとその中の iframe は異なるドメインにあるため、ページに js コードを記述しても iframe 内のコンテンツを取得することはできません。

2. なぜドメインを越える必要があるのですか

ブラウザのオリジンポリシーの制限により、2つの異なるドメイン間でデータを直接転送したり、通信したりすることはできません。たとえば、次のコード:

<script type="text/javascript" src="jquery.js"></script>
<script>
$.post(&#39;https://www.baidu.com&#39;,function(text){
	console.log(text);
});
</script>
ログイン後にコピー
実行結果は次のようになります: 3. クロスを達成する方法ドメイン


1 、jsonp を介したクロスドメイン (制限事項

のため)


js では、XMLHttpRequest を直接使用して異なるドメインのデータをリクエストすることはできませんが、js スクリプト ファイルを導入できます。ページ上の異なるドメイン上での実行は可能ですが、jsonp はこの機能を使用してそれを実現します。

たとえば、特定のドメインにindex.htmlページがあり、その中のコードは別のドメイン(http://www.php.cn/など)のjsonデータを取得するためにajaxを使用する必要があります。 )
実装方法は以下の通りです

index.htmlの内容は以下の通りです

<script>
//回调函数
function show(oJson){
	//dosomething
	console.log(oJson[&#39;str&#39;]);
}
</script>
<script type="text/javascript" src="http://www.findme.wang/test.php?callback=show&name=dqs"></script>
ログイン後にコピー


在http://www.php.cn/域上,要有一个test.php文件,返回一个js文件,并在该文件中,调用回调方法show,内容如下

$callback=$_GET[&#39;callback&#39;];
$name=$_GET[&#39;name&#39;];
$data=array(&#39;str&#39;=>&#39;hello,&#39;.$name);
echo $callback.&#39;(&#39;.json_encode($data,JSON_UNESCAPED_UNICODE).&#39;)&#39;;
ログイン後にコピー

结果如下:


原理分析:通过script标签引入一个js文件,这个js文件载入成功后会执行我们在url参数中指定的函数,并且会把我们需要的json数据作为参数传入。当然jsonp是需要服务器端的页面进行相应的配合的。

2、通过修改window.name来跨子域(针对限制二)

为了更加现实效果,我在本地http://www.php.cn/下的index.html文件通过iframe引入了http://www.php.cn/和http://www.php.cn/,通过JS获取iframe文件中的内容。

index.html文件

<script type="text/javascript" src="jquery.js"></script>
<iframe src="http://www.findme.wang/test.php" id="test_box1"></iframe>
<iframe src="http://localhost/test.php" id="test_box2"></iframe>
<script type="text/javascript">
	$(function(){
		//针对不同的域名
		$(&#39;#test_box1&#39;).load(function(){
			//我们能获取到window对象,但是没法获取window对象的属性和方法
			var oiframe1=$("#test_box1");
			var doc1=oiframe1.contents();
			console.log(doc1);
			var p1=doc1.find("#p1");
			console.log(p1.html());
		})

		//针对相同的域名
		$(&#39;#test_box2&#39;).load(function(){
			var oiframe2=$("#test_box2");	
			var doc2=oiframe2.contents();
			console.log(doc2);
			var p2=doc2.find("#p2");
			console.log(p2.html());
		});
	});
</script>
ログイン後にコピー

文件如下

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
	<title>测试</title>
</head>
<body>
	<p id="p1">
		域名:www.findme.wang;你好啊!!!
	</p>
</body>
</html>
ログイン後にコピー


文件如下

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
	<title>测试</title>
</head>
<body>
	<p id="p2">
		域名:localhost;你好啊!!!
	</p>
</body>
</html>
ログイン後にコピー

结果如下


从结果可以看出,这个案例证实了浏览器中不同域的框架之间是不能进行js的交互操作的。怎样实现他们的交互操作呢?使用HTML5中新引进的window.postMessage方法来跨域传送数据。window.postMessage(message,targetOrigin) 方法是html5新引进的特性,可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源,目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。

补充

1.如何获取iframe的document对象

W3C的标准告诉我们,可以通过Dom对象的contentDocument属性来返回文档对象。


var doc = document.getElementById(&#39;mainFrame&#39; ).contentDocument
ログイン後にコピー

IE8开始支持,如果你的项目不用兼容IE6,IE7的话使用这种方式最好。

IE6,IE7需要如此访问


var doc = document.frames[&#39;mainFrame&#39;].document;
ログイン後にコピー

兼容方式:


var doc = document.getElementById(&#39;mainFrame&#39; ).contentDocument || document.frames['mainFrame'].document;
ログイン後にコピー

以上是Javascript原生方法:

使用Jquery则简单些

$(&#39;#frameID&#39;).load(function () {
    $(&#39;#frameID&#39;).contents().find(&#39;#p1&#39;);//在frame中找id为p1的元素
});
ログイン後にコピー

以上就是JS跨越问题解决方法的内容,更多相关内容请关注PHP中文网(www.php.cn)!


関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート