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

31次阅读

共计 2906 个字符,预计需要花费 8 分钟才能阅读完成。

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

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

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

otherWindow.postMessage(message, targetOrigin);

该方法使用 2 个参数,第一个参数为所发送的消息文本,但也可以是任何 javascript 对象,第二个参数是接收消息的对象窗口的 url 地址(比 如:http/) , 但是我们也可以在 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,””); } 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>。’,””);},false);

当我点击 abc.html 页面后,可以看到效果如下,从 def.html 返回内容了。如下我们需要知道如下几条信息:

通过对 window 对象的 message 事件进行监听,可以接收消息。

通过访问 message 事件的 origin 属性,可以获取消息的发送源。

通过访问 message 事件的 data 属性,可以取得消息内容。

使用 postMessage 方法发送消息。

通过访问 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,””); } 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: ”, type:’POST’, dataType:’text’, //data: {msg:e.data}, success: function(res) {var parentwin = window.parent; parentwin.postMessage(res,””);// 跨域发送数据 } }); };

test.php 代码如下:

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

正文完
 0