关于javascript跨域的解决方法
由于在自己这么多年项目开发中对跨域这方面应用的很少,近几次面试都涉及到了这个跨域的问题。因此,这几天对跨域深深的研究了一下,希望以后如果能应用到的话可以作为自己的参考。
什么是跨域?
在javascript开发中,出于安全性的考虑,javacript禁止对不同域名,端口服务器进行访问,也就是说只能访问同一个域名,而且也是同一个端口号上的数据才能进行自由访问,其他的就不能直接访问。也就是我们说的**同源策略**,但是在日常应用中,我们有这么几个方法可以替我们解决这个问题。接下来我们就简单的介绍一个。
document.domain+iframe
使用document.domain+iframe可以解决一些跨域的问题,但是他们联合起来只能解决主域相同二级域名不同的情况,如果主域不同这个是不起作用的。具体做法就是在两个不同的域名的html中加入document.domain这个对象,并对其赋值,在赋值名的html下创建iframe标签,然后我们操作iframe里的页面的contentDocument即可。
document.domain = 'www.foo.com';
var iframe1 = document.createElement('iframe');
iframe1.src = 'http://script.foo.com/hoo.html';
iframe1.display = 'none;//设置隐藏就不会影响页面的结构
document.appendChild(iframe1);
iframe1.onload = function(){
var content = iframe1.contentDocument ||
iframe1.contentWindow.document;
//通过content就可以访问iframe1上的标签额内容了。
console.log(document.getElementById('div#nav').childNodes[2].innerHTML);
};
postMessage
在HTML5最新特性中,我们有一个新功能就是跨文档消息传输**cross document messaging**.postMessage()方法允许来自不同源的脚本采用异步的方式进行有限的通信,可以实现跨文档,多窗口,跨域消息传递。
postMessage(data,origin);//接受两个参数
// data:要传递的数据,该参数值可以是javascript中的任意类型数据或者是可以复制的对象。由于某些浏览器只能借此处理字符串参数。所以我们在传递参数的时候使用JSON.stringify()函数进行序列化。
//origi:字符串参数,定义目标窗口的源,即协议(http?)+主机+端口号。后面的url会被忽略,因为主要是前面这部分。postMessage()函数只会将message传递给指定的目标窗口。
当我们将这个参数设置为“*”时,就可以传递给任意的窗口,如果要指定和当前窗口同源的话,可以设置为'/'.
例:
在http://foo.com/通过postMessage()方法向跨域的http://goo.com/传递消息。
//在foo.com下面应该这样写:
window.frames[0].postMessage('helloWorld','http://goo.com/');
//在http://goo.com/接收消息,通过监听window的message事件就可以获取到跨域的信息了。
window.addEventListener('message',function(e){
if(e.source != window.parent){
return;
}else{
var message = container.innerHTML;
window.parent.postMessage(message,'*');
}
});
//在这个e参数上面有几个重要的属性:
// data:从跨域传递过来的消息。
// source:发送这个消息的窗口对象
// origin:发送消息窗口的源(包括:协议+主机+端口号)
其他的一些跨域方法如:动态创建script标签,location.hash,window.name等方法。在这里就不一一赘述了。