视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
JS跨越问题解决方法
2020-11-27 20:24:38 责编:小采
文档

一.同源策略的

首先,我们需要知道跨域就是在不同的域之间进行数据传输或通信。只要协议、域名、端口有任何一个不同,都被当作是不同的域。当要想跨域,就得理解浏览器的同源策略。

其之一就是我们说的不能通过ajax的方法去请求不同源中的文档。 它的第二个是浏览器中不同域的框架之间是不能进行js的交互操作的。

关于第二个,比如,有一个页面,它的地址是http://www.gxlcms.com/ , 在这个页面里面有一个iframe,它的src是http://www.gxlcms.com/, 很显然,这个页面与它里面的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.gxlcms.com/)的json数据

实现方式如下

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.gxlcms.com/域上,要有一个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.gxlcms.com/下的index.html文件通过iframe引入了http://www.gxlcms.com/和http://www.gxlcms.com/,通过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方法。

补充

1.如何获取iframe的document对象

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的元素
});

下载本文
显示全文
专题