您的位置:首页 > Web前端 > JavaScript

简单研究跨域的几种方法

2016-05-19 21:28 447 查看
一、window.postMessage()。

        MDN上有详细的实例代码。以下是一个简单实例。

        发送方代码

var con = document.getElementsByTagName('iframe')[0].contentWindow;con.postMessage('hello','http://192.168.110.2');

        
        接收方代码

window.addEventListener('message',receive,false);function receive(event){	var origin = event.origin || event.originalEvent.origin;	if (origin !== "http://192.168.110.2")return;	alert(event.data);//简单处理}

        
        上述代码中,关键部分是发送方需要获取到接收方窗口的引用,这意味着接收方窗口必须在你的浏览器上打开着,而且是加载完毕的,发送方包含一个data(数据)和origin(接收方的协议加ip,端口号与协议默认端口不符的话就需要加上它)。接收方window为message操作类型绑定一个函数,安全性就体现在这个函数里了,先判断是不是正确
4000
的发送方,再处理消息。

        实际写demo的时候注意到了以下两点:1、接受消息的页面如果没有加载完,那么就不会有反馈,所以用window.open需要待其加载完毕再发送消息。2、发送对象类型是window,如果是iframe标签,则对象为document.getElementsByTagName("iframe")[0].contentWindow,或者window.frames[0]。

        

二、jsonp

        加载js代码的标签script有src属性,和其他标签的src一样,它也是可以跨域的。jsonp跟一个普通ajax的get请求效果差不多,只是写法不太一样,但是却可以跨域,这就体现与ajax的不同了。几种方法中,似乎就这种应用最普遍了。

        这里的原理也比较简单,新建一个script脚本,src为一个普通get请求,请求的内容就是一个函数和数据(类似这种形式,hello(data);),这里的hello需要作为参数传递过去,而且hello函数声明已经事先写好了。部分代码如下:

<body><p>原始页面内容</p>	<button onclick="helloworld()"> hello</button></body><script type="text/javascript">function helloworld(){var script = document.createElement('script');var url0 = 'http://192.168.193.88/scdbackup/test0.php?callback=hello';script.setAttribute('src', url0);document.body.appendChild(script);}	function hello(data){document.getElementsByTagName('p')[0].innerHTML = data.message;}</script>

        

        上述代码中,test0.php中定义的返回数据类型为json,类似于这种形式{message:'hello'}。所以点击按钮后,标签p的内容会被替换为hello。

三、CORS

        cross origin resources sharing---跨域资源共享,即设置Access-Control-Allow-Origin。Ubuntu下的apache2找不到配置headers_module的地方,真是醉人的配置文件。一般情况下,这玩意是默认开启的,只需要找到<Directory />,加上Header set Access-Control-Allow-Origin *就能让任何其他域都能访问到,如果想要限定某个ip,只需把*替换为某个ip就好。php中,只要在需要被其他域访问到的php文件开头中加上header("Access-Control-Allow-Origin:*");
即可。服务器和php随便配置一项即可使用CORS,而使用CORS的方法则与ajax一毛一样,需要注意的是url要带上协议。

        

四、window.name

        这是个古老的方法。主要流程就是设置一个iframe,src设为跨域请求数据地址,onload的时候获取window.name,再将src改成本域下某个文件,导致再次onload,此时获取name值处理即可。处理完了之后,可以删除这个iframe,防止被其他页面读取。简单代码如下:

<body>
<p>原始页面内容</p>
<button onclick="helloworld()"> hello</button&g
ca74
t;
</body>
<script type="text/javascript">
 
function helloworld(){
var ifr = document.createElement('iframe');
ifr.style.display = 'none';
ifr.src = 'http://192.168.193.88/test1.php';
ifr.onload = function(){
	ifr.onload = function(){
document.getElementsByTagName('p')[0].innerHTML = ifr.contentWindow.name;
document.body.removeChild(ifr);
}
ifr.src = 'http://192.168.193.1/test.php';
}
document.body.appendChild(ifr);
}
 
</script>


        另外还有一种方法是document.domain+iframe的设置,不过这是主要针对主域相同而子域不同的跨域请求,使用范围不是很广就不提了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息