우선, 알아두세요크로스 도메인은 서로 다른 도메인 간의 데이터 전송 또는 통신을 의미합니다. 프로토콜, 도메인명, 포트에 차이가 있는 한 , 작업은 다른 영역으로 간주됩니다. 크로스 도메인을 하려면 브라우저의 동일 출처 정책 제한을 이해해야 합니다.
한계 중 하나는 우리가 말하는 것은 ajax 방식을 통해 다양한 소스의 문서를 요청할 수 없다는 것입니다. 두 번째 제한 사항은 브라우저의 다른 도메인에 있는 프레임이 js 와 상호 작용할 수 없다는 것입니다.
두 번째 제한 사항에 대해 예를 들어 주소가 http://www.php.cn/인 페이지가 있는데 이 페이지에는 은 페이지의 iframe이고 해당 src는 http://www.php.cn/입니다. 분명히 이 페이지와 그 안에 있는 iframe은 서로 다른 도메인에 있으므로 페이지에 js 코드를 작성하여 얻을 수 없습니다. iframe의 콘텐츠입니다.
을 교차하는 이유 서버 오리진 정책 제한으로 인해 서로 다른 두 도메인 간의 데이터 전송이나 통신을 직접 수행할 수 없습니다. 다음 코드와 같습니다:
<script type="text/javascript" src="jquery.js"></script> <script> $.post('https://www.baidu.com',function(text){ console.log(text); }); </script>
실행 결과는 다음과 같습니다.
1. jsonp를 통한 크로스 도메인(제한 사항 -)
js에서는 XMLHttpRequest를 직접 사용하여 다른 도메인의 데이터를 요청할 수 없지만 페이지의 다른 도메인에 js 스크립트 파일을 도입하는 것이 가능합니다. jsonp는 이 기능을 사용하여 이를 달성합니다. .
예를 들어 특정 도메인 아래에 index.html 페이지가 있는 경우 해당 페이지의 코드는 ajax를 사용하여 다른 도메인(예: http://www.php.cn/)
은 다음과 같이 구현됩니다.
index.html의 내용은 다음과 같습니다.
<script> //回调函数 function show(oJson){ //dosomething console.log(oJson['str']); } </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['callback']; $name=$_GET['name']; $data=array('str'=>'hello,'.$name); echo $callback.'('.json_encode($data,JSON_UNESCAPED_UNICODE).')';
结果如下:
原理分析:通过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(){ //针对不同的域名 $('#test_box1').load(function(){ //我们能获取到window对象,但是没法获取window对象的属性和方法 var oiframe1=$("#test_box1"); var doc1=oiframe1.contents(); console.log(doc1); var p1=doc1.find("#p1"); console.log(p1.html()); }) //针对相同的域名 $('#test_box2').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方法。
W3C的标准告诉我们,可以通过Dom对象的contentDocument属性来返回文档对象。
var doc = document.getElementById('mainFrame' ).contentDocument
IE8开始支持,如果你的项目不用兼容IE6,IE7的话使用这种方式最好。
IE6,IE7需要如此访问
var doc = document.frames['mainFrame'].document;
兼容方式:
var doc = document.getElementById('mainFrame' ).contentDocument || document.frames['mainFrame'].document;
以上是Javascript原生方法:
使用Jquery则简单些
$('#frameID').load(function () { $('#frameID').contents().find('#p1');//在frame中找id为p1的元素 });
以上就是JS跨越问题解决方法的内容,更多相关内容请关注PHP中文网(www.php.cn)!