本文主要是记录使用window.postMessage解决ajax跨域问题的方案,实践检验。javascript
window.postMessage 是一个安全的跨源通讯的方法。通常状况下,当且仅当执行脚本的页面使用相同的协议(一般都是 http)、相同的端口(http默认使用80端口)和相同的 host(两个页面的 document.domain 的值相同)时,才容许不一样页面上的脚本互相访问。 window.postMessage 提供了一个可控的机制来安全地绕过这一限制,当其在正确使用的状况下。html
跨域问题对于前端从业者而言绝对不会陌生,若是您是一位喜欢google或者百度的自学爱好者,必然会在检索的页面上看到不一样的解决方案。这些解决方案从大类上来看,大体可分为前端解决方案,后端解决方案,先后联调解决方案。前端
经过设置后端接口访问的权限,好比设置access-origin的源策略,让其设置为通配符*,或者发送请求的域名便可,最先的时候设置apache下的访问策略实践过,可解决跨域访问的问题。java
后端经过返回特定代码片断的形式,前端经过jsonp方式发送请求,但因为是script的方式因此对于post请求无能为力,只能处理get类型。web
首先,能够一块儿来理解一下整个方案的思路和结构ajax
在实现的时候,如今a页面上获取嵌入的iframe的窗口对象,而后向其发送一条消息,消息体是a页面的url,可是具体实现的时候发现数据没发送过去,这个待排查。而后的解决方案就是b页面先广播一条数据,请求握手,而后a页面监听到消息后再根据消息源对象来发送指定数据,可行。apache
具体示例代码以下:
业务页面逻辑,这里的type为1时表示是握手消息,消息数据可忽略;当type为2时,表示是数据消息,消息体中的data属性为须要的数据内容json
window.addEventListener('message',function (event) {
//alert('message comes');
var origin = event.origin || event.originalEvent.origin;
console.log(event.data);
var ret = JSON.parse(event.data);
if(ret.type == 1){
//回复消息
event.source.postMessage(window.location.href,origin);
}
if(ret.type == 2){
console.log(ret);
}
},false);
中转页面逻辑,先构造消息体,页面加载时先发送一条广播消息,跟业务页面进行握手;而后根据业务页面传递的参数来作相应的接口调用。后端
//是否为第一次响应消息的标志
var flag = true;
var fWindow = window.parent;
//var url = fWindow.location.href;
var data = {
//type为1时,表示是握手
type : 1
};
//第一次握手,告诉父页面把相关信息发送过来
fWindow.postMessage(JSON.stringify(data) ,'*');
window.addEventListener('message',function (e) {
if(!flag)
return;
var origin = e.origin || e.originalEvent.origin;
console.log('data from father page ' + e.data);
//返回验证信息
e.source.postMessage(JSON.stringify(data),origin);
//重置标志
flag = false;
});
通过先后端调试,验证此方案可行,具体逻辑请自行修改相应的逻辑便可。但愿对各位读者有用,也欢迎一块儿讨论。跨域