js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据。只要协议、域名、端口有任何一个不同,都被当作是不同的域。一般情况下浏览器会阻止这些请求,认为这是不安全的,有以下几种解决措施。
一、通过jsonp跨域
在js中,我们直接用XMLHttpRequest请求不同域上的数据时,是不可以的。但是,在页面上引入不同域上的js脚本文件却是可以的,jsonp正是利用这个特性来实现的。
比如,有个页面,它里面的代码需要利用ajax获取一个不同域上的json数据,假设这个json数据地址是http://test.com/data.php,那么该页面中的代码就可以这样:
function getData(){ console.log(data); }当然也可以使用jQuery的ajax跨域操作实现跨域,具体实现如下:
$(function(){ $.ajax( { type:'get', url : 'http://www. .com/validate.php?loginuser=lee&loginpass=123456', dataType : 'jsonp', jsonp:"jsoncallback", success : function(data) { alert("用户名:"+ data.user +" 密码:"+ data.pass); }, error : function() { alert('fail'); } } ); })
二,iframe 跨域
页面中增加一个iframe元素,在需要调用get请求的时候,将iframe的src设置为get请求的url即可发起get请求的调用。
var url = "xxx";
$("#iframe").attr("src", url);//跨域,使用iframe
iframe方式强于jsonp,除了可以处理http请求,还能够跨域实现js调用。
三,通过修改document.domain来跨子域
我们只要把http://www.example.com/a.html 和 http://example.com/b.html这两个页面的document.domain都设成相同的域名就可以了。但要注意的是,document.domain的设置是有限制的,我们只能把document.domain设置成自身或更高一级的父域,且主域必须相同。例如:a.b.example.com 中某个文档的document.domain 可以设成a.b.example.com、b.example.com 、example.com中的任意一个,但是不可以设成 c.a.b.example.com,因为这是当前域的子域,也不可以设成baidu.com,因为主域已经不相同了。
四,window.name来跨域
Window.name属性是保存在浏览器端的,window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置
a页面设置window.name属性:
window.name="你好";
b页面访问该属性:
alert(window.name);
但要保证在同一个窗口下访问两个不同的页面。
五,window.postMessage实现跨域
postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。
postMessage(data,origin)方法接受两个参数
1.data:要传递的数据,html5规范中提到该参数可以是JavaScript的任意基本类型或可复制的对象,然而并不是所有浏览器都做到了这点儿,部分浏览器只能处理字符串参数,所以我们在传递参数的时候需要使用JSON.stringify()方法对对象参数序列化。
2.origin:字符串参数,指明目标窗口的源,协议+主机+端口号[+URL],URL会被忽略,所以可以不写,这个参数是为了安全考虑,postMessage()方法只会将message传递给指定窗口,当然如果愿意也可以建参数设置为"*",这样可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。
3.在发送数据窗口执行:otherWindow.postMessage(msg,origin)
otherWindow:表示接受数据的窗口的window对象,包括iframe的contentWindwohe和通过window.open打开的新窗口。
msg表示要发送的数据,包扩字符串和对象(ie9以下不支持,可以利用字符串和json互换)。
origin表示接收的域名。
4.在接受的窗口监听window的message事件,回掉函数参数接受一个事件对象event,包括的属性有:
data:接受的数据
origin:发送端的域
source:发送端的DOMWindow对象
示例代码如下:
1.在父框架页面index.html发送obj对象给远程服务器的b.html,该页面是通过iframe加载的,如下
html>
window.postMessage
2.在远程页面b.html中监听message事件,先通过origin属性判断下数据来源的域是否可信任,加强安全措施。具体代码如下:
html>
this is my server
3.在控制输出结果:
除了以上几种方法外,还有flash、在服务器上设置代理页面等跨域方式,之后会继续补充完善。