使用HTML5中postMessage 实现ajax中的POST跨域问题

HTML5中提供了在网页文档之间相互接收与发送信息的功能。使用这个功能,只要获取到网页所在窗口对象的实例,不仅仅同源(域+端口号)的web网页之间可以互相通信,甚至可以实现跨域通信。

浏览器支持程度:IE8+,firefox4+,chrome8+  opera10+

1. 首先,要想接收从其他的窗口发过来的消息,就必须对窗口对象的message事件进行监听,如下代码:

window.addEventListener(“message”, function(){},false);

2. 其次,需要使用window对象的postMessage方法向其他窗口发送消息,该方法定义如下所示:

otherWindow.postMessage(message, targetOrigin);

该方法使用2个参数,第一个参数为所发送的消息文本,但也可以是任何javascript对象,第二个参数是接收消息的对象窗口的url地址(比如:http:127.0.0.1:8080/) , 但是我们也可以在url地址字符串中使用通配符”*”, 指定全部的域下,但是我们还是建议使用特定的域名下,otherWindow为要发送窗口对象的引用。

Demo演示:

假如现在我在hosts文件下 ,绑定2 个域名如下:

127.0.0.1       abc.example.com

127.0.0.1        longen.example.com

现在假如在abc.example.com域下有一个abc.html页面,在longen.example.com域下有def.html页面,现在我是希望这2个不同域名下的页面能互相通信,abc.html代码如下:

<form>
      <p>
        <label for="message" style="color:red;font-size:24px;">给iframe子窗口发一个信息:</label>
        <input type="text" name="message" value="send" id="message" />
        <input type="submit" value="submit" id="submit"/>
      </p>
</form>
<h4>目标iframe传来的信息:</h4>
<p id="test">暂无信息</p> 

 <iframe id="iframe"
    src="http://longen.example.com/webSocket/def.html" style="display:none"></iframe>

JS代码如下:

var win = document.getElementById("iframe").contentWindow;

document.getElementById("submit").onclick = function(e){
    e.preventDefault();
    win.postMessage(document.getElementById("message").value,"http://longen.example.com");
}  

window.addEventListener("message",function(e){
     e.preventDefault();
     document.getElementById("test").innerHTML = "从" + e.origin + "那里传过来的消息:\n" + e.data;
},false);

Def.html代码如下:

HTML代码:

<form>
      <p>
        <label for="message">给父窗口abc.html发个信息:</label>
        <input type="text" name="message" value="send" id="message" />
        <input type="submit" />
      </p>
 </form>
 <p id="test2">暂无信息。</p>

JS代码如下:

var parentwin = window.parent;
window.addEventListener("message",function(e){
       document.getElementById("test2").innerHTML = "从父窗口传来的域" +e.origin + ",和内容数据:" + e.data;
       parentwin.postMessage(‘HI!你给我发了"<span>‘+e.data+‘"</span>。‘,"http://abc.example.com");
},false);

当我点击abc.html页面后,可以看到效果如下,从def.html返回内容了。如下:

我们需要知道如下几条信息:

  1. 通过对window对象的message事件进行监听,可以接收消息。
  2. 通过访问message事件的origin属性,可以获取消息的发送源。
  3. 通过访问message事件的data属性,可以取得消息内容。
  4. 使用postMessage方法发送消息。
  5. 通过访问message事件的source属性,可以获取消息发送源的窗口对象(准确的说,应该是窗口的代理对象)。

有了上面的基本知识点,我们可以延伸为实现ajax POST跨域的问题。

二:使用postMessage 知识点解决 ajax中POST跨域问题。

原理:原理也很简单,假如我们的域名abc.example.com下的abc.html页面需要发ajax请求(跨域,域名为longen.example.com)下,那么我们还是先跨页面文档的形式,和上面一样,我们可以现在longen.example.com下 建立一个页面,比如叫def.html. 那么我们现在还是在 abc.html 页面嵌入一个隐藏域iframe src路径指向longen.example.com域下def,html页面。过程还是和跨文档类似,只是现在在def.html页面中 在window.onmessage 事件内写ajax请求即可,如下代码:

abc.example.com下的abc.html页面如下:

html代码和上面一样,下面是JS代码:

var win = document.getElementById("iframe").contentWindow;

document.getElementById("submit").onclick = function(e){
      e.preventDefault();
      win.postMessage(document.getElementById("message").value,"http://longen.example.com/");
}  

window.addEventListener("message",function(e){
    e.preventDefault();
    alert(typeof e.data)
    var json = JSON.parse(e.data);
     console.log(json);
    alert(json.url)},false);

def.html代码如下:

JS代码如下:

//获取跨域数据
window.onmessage = function(e){
     $.ajax({
          url: ‘http://longen.example.com/webSocket/test.php‘,
          type:‘POST‘,
          dataType:‘text‘,
          //data: {msg:e.data},
          success: function(res) {
               var parentwin = window.parent;
               parentwin.postMessage(res,"http://abc.example.com");//跨域发送数据
          }
      });
 };  

test.php代码如下:

<?php
    $data=array(
     url =>1,
      name =>‘2‘,
      ‘xx-xx‘=>"xx"
 );
 echo json_encode($data);
?>

如上实现方式 就可以实现ajax post跨域了。

时间: 2024-07-30 05:10:38

使用HTML5中postMessage 实现ajax中的POST跨域问题的相关文章

Ajax 调用webservice 解决跨域请求和发布到服务器后本地调用成功外网失败的问题

    webservice 代码 1 /// <summary> 2 /// MESService 的摘要说明 3 /// </summary> 4 [WebService(Namespace = "http://tempuri.org/")] 5 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 6 //[System.ComponentModel.ToolboxItem(false)

Springboot如何优雅的解决ajax+自定义headers的跨域请求[转]

1.什么是跨域 由于浏览器同源策略(同源策略,它是由Netscape提出的一个著名的安全策略.现在所有支持JavaScript 的浏览器都会使用这个策略.所谓同源是指,域名,协议,端口相同.),凡是发送请求url的协议.域名.端口三者之间任意一与当前页面地址不同即为跨域. 具体可以查看下表: 2.springboot如何解决跨域问题 1.普通跨域请求解决方案: ①请求接口添加注解@CrossOrigin(origins = "http://127.0.0.1:8020", maxAge

WebService学习笔记-Ajax通过servlet请求跨域Webservice

ajax不能直接访问跨域的Webservice,但是可以通过servlet去访问跨域的Webservice 页面 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

jQuery中Ajax+Spring MVC实现跨域请求

项目开发中,某个可独立.也可集成的子业务模块须要向外开放相关API接口,先说下项目本身使用了jersery来实现RESTful webservice以名词形式公布API.有意思的是在实际的操作中同事却通过Ajax跨域请求的方式去调用该API,先不说成功与否,这样的方式本就是"滑稽"的.和他一起探讨了此种做法的不合理性,之后选择jersey client的方式进行远程调用.只是他在跨域请求中遇到了问题,自己闲暇时间予以解决,这才是此篇文章的由来. jQuery对跨域请求有两种解决方式各自

ajax(同源与跨域)

7. http协议 协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则 HTTP协议,即超文本传输协议(Hypertext transfer protocol).是一种详细规定了浏览器和服务器之间互相通信的规则,HTTP协议分为请求 和响应 两个部分组成. 7.1. 请求与请求报文 get请求的请求报文详解 //--------------------------请求行-------------------------------- // GET 请求方式 // /day0

ajax 设置Access-Control-Allow-Origin实现跨域访问

ajax跨域访问是一个老问题了,解决方法很多,比较常用的是JSONP方法,JSONP方法是一种非官方方法,而且这种方法只支持GET方式,不如POST方式安全. 即使使用jquery的jsonp方法,type设为POST,也会自动变为GET. 官方问题说明: “script”: Evaluates the response as JavaScript and returns it as plain text. Disables caching by appending a query string

Vue.js&mdash;&mdash;基于$.ajax实现数据的跨域增删查改

概述 之前我们学习了Vue.js的一些基础知识,以及如何开发一个组件,然而那些示例的数据都是local的.在实际的应用中,几乎90%的数据是来源于服务端的,前端和服务端之间的数据交互一般是通过ajax请求来完成的. 说起ajax请求,大家第一时间会想到jQuery.除了拥有强大的DOM处理能力,jQuery提供了较丰富的ajax处理方法,它不仅支持基于XMLHttpRequest的ajax请求,也能处理跨域的JSONP请求. 之前有读者问我,Vue.js能结合其他库一起用吗?答案当然是肯定的,V

jquery ajax使用JSONP解决跨域问题

参考文章:http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html 什么是跨域 JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象.但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦.这里把涉及到跨域的一些问题简单地整理一下: 首先什么是跨域,简单地理解就是因为JavaScript同源策略的限制,a.com 域名下的js无法操作b.com或是c.a.com域名下的对象

Ajax+Spring MVC实现跨域请求(JSONP)JSONP 跨域

JSONP原理及实现 接下来,来实际模拟一个跨域请求的解决方案.后端为Spring MVC架构的,前端则通过Ajax进行跨域访问. 1.首先客户端需要注册一个callback(服务端通过该callback(jsonp)可以得到js函数名(jsonpCallback)),然后以JavaScript语 法的方式,生成一个function 2.接下来,将JSON数据直接以入参的方式,放置到function中,这样就生成了一段js语法文档,返回给客户端. 3.最后客户端浏览器动态的解析script标签,