window.postMessage解决前端ajax跨域问题

原创 2016年08月30日 19:11:35

postMessage畅快解决跨域问题

本文主要是记录使用window.postMessage解决ajax跨域问题的方案,实践检验。

window.postMessage简介

window.postMessage 是一个安全的跨源通信的方法。一般情况下,当且仅当执行脚本的页面使用相同的协议(通常都是 http)、相同的端口(http默认使用80端口)和相同的 host(两个页面的 document.domain 的值相同)时,才允许不同页面上的脚本互相访问。 window.postMessage 提供了一个可控的机制来安全地绕过这一限制,当其在正确使用的情况下。

跨域问题对于前端从业者而言绝对不会陌生,如果您是一位喜欢google或者百度的自学爱好者,必然会在检索的页面上看到不同的解决方案。这些解决方案从大类上来看,大致可分为前端解决方案,后端解决方案,前后联调解决方案。

后端方案

通过设置后端接口访问的权限,比如设置access-origin的源策略,让其设置为通配符*,或者发送请求的域名即可,最早的时候设置apache下的访问策略实践过,可解决跨域访问的问题。

前后端联调方案

后端通过返回特定代码片段的形式,前端通过jsonp方式发送请求,但由于是script的方式所以对于post请求无能为力,只能处理get类型。

在页面上通过嵌套指定域名下的中转页面来进行接口调用,但是如果需要传递数据的话可通过window.name来保存并传输接口数据,本人未实践,各位可根据网友的方案自行测试,不赘述。
在页面上通过iframe嵌套目标接口同域名下的页面,请求数据交给iframe页面,实际页面获取数据时,通过window.postMessage来跟iframe的页面进行数据交换。这也是本文要介绍的方案,实际验证可用。

首先,可以一起来理解一下整个方案的思路和结构

Created with Raphaël 2.1.0www.a.com/a.htmlwww.a.com/a.htmlwww.b.com/b.htmlwww.b.com/b.htmlwww.b.com/cgiwww.b.com/cgi根据消息的源将本页面的url回发ajax请求cgi返回的数据post到a域下的a页面

在实现的时候,现在a页面上获取嵌入的iframe的窗口对象,然后向其发送一条消息,消息体是a页面的url,但是具体实现的时候发现数据没发送过去,这个待排查。然后的解决方案就是b页面先广播一条数据,请求握手,然后a页面监听到消息后再根据消息源对象来发送指定数据,可行。

具体示例代码如下:
业务页面逻辑,这里的type为1时表示是握手消息,消息数据可忽略;当type为2时,表示是数据消息,消息体中的data属性为需要的数据内容

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;
});

经过前后端调试,验证此方案可行,具体逻辑请自行修改相应的逻辑即可。希望对各位读者有用,也欢迎一起讨论。

看小白如何解决ajax跨域问题

由于此前很少写前端的代码(哈哈,不合格的程序员啊),最近项目中用到json作为系统间交互的手段,自然就伴随着众多ajax请求,随之而来的就是要解决ajax的跨域问题。本篇将讲述一个小白从遇到跨域不知道...
  • Function_JX_
  • Function_JX_
  • 2015年07月29日 11:30
  • 1010

chrome浏览器解决ajax跨域问题

@方法一 1、右键谷歌快捷方式,选择“属性”。 2、打开属性窗口,切换到“快捷方式”选项卡。 3、在目标路径的后面添加【 --disable-web-security】,其中chrome.exe与--...
  • sky_beyond
  • sky_beyond
  • 2017年01月05日 15:36
  • 457

前端面试之跨域请求

背景跨域是由浏览器的同源策略引起的,是指页面请求的url地址,必须与浏览器上url地址处于同域上(即域名,端口,协议相同)。这是为了防止某域名下的接口被其他域名下的网页非法调用,是浏览器对javasc...
  • zhang070514
  • zhang070514
  • 2017年08月26日 18:06
  • 241

ajax跨域问题(三种解决方案)

为什么会出现跨域 跨域问题来源于JavaScript的同源策略,即只有 协议+主机名+端口号 (如存在)相同,则允许相互访问。也就是说JavaScript只能访问和操作自己域下的资源,不能访问和操作其...
  • u014727260
  • u014727260
  • 2017年05月28日 17:23
  • 3502

ajax跨域问题以及解决方案

在工作中,大家应该都遇到过ajax跨域问题,浏览器的错误如下: XMLHttpRequest cannot load http://目标地址 No 'Access-Control-Allow-Orig...
  • csdn_ds
  • csdn_ds
  • 2017年06月24日 14:14
  • 4768

Ajax 跨域问题解决最好方案

本文通过设置Access-Control-Allow-Origin来实现跨域。 例如:客户端的域名是client.w3cschool.cc,而请求的域名是server.w3cschool.cc。 如果...
  • l1028386804
  • l1028386804
  • 2015年06月19日 21:53
  • 2805

完美解决AJAX跨域问题

完美解决AJAX跨域问题 解决的办法,大概有如下几种: 1. 使用中间层过渡的方式(可以理解为“代理”): 中间过渡,很明显,就是在AJAX与不同域的服务器进行通讯的中间加一层过...
  • github_36111469
  • github_36111469
  • 2016年11月10日 19:11
  • 958

微服务网关ajax转发跨域的问题解决方案

浏览器端报错:“NetworkError: 403 Forbidden - http://192.168.10.147:8080/mytest/helloworld” helloworld 已阻止...
  • han1196639488
  • han1196639488
  • 2017年04月19日 15:09
  • 966

前端解决跨域问题的8种方案(最新最全)

前端解决跨域问题的8种方案(最新最全) 2013-10-31 19:25 阅读(933) 评论(8) 编辑 收藏 1.同源策略如下: URL 说明 是否允许...
  • GaraMaps
  • GaraMaps
  • 2016年09月13日 21:47
  • 1840

如何解决ajax跨域问题(转) --使用两种 jsony方法

由 于此前很少写前端的代码(哈哈,不合格的程序员啊),最近项目中用到json作为系统间交互的手段,自然就伴随着众多ajax请求,随之而来的就是要解决 ajax的跨域问题。本篇将讲述一个小白从遇到跨域不...
  • jintianhen1
  • jintianhen1
  • 2015年04月29日 13:31
  • 578
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:window.postMessage解决前端ajax跨域问题
举报原因:
原因补充:

(最多只允许输入30个字)