技术中心

这里象征着我们的态度和能力

HTML5:postMessage实现Ajax跨域请求
作者:中国IT实验室    来源:中国IT实验室    发布时间:2012-09-14      浏览次数:11733
分享到:
欢迎进入Java社区论坛,与200万技术人员互动交流 >>进入

    由于同源策略的限制,Javascript存在跨域通信的问题,典型的跨域问题有iframe与父级的通信等。

    常规的几种解决方法:

    (1) document.domain+iframe; (2) 动态创建script; (3) iframe+location.hash; (4) flash。

    这里不细说这几种方法,记录的是HTML5的window.postMessage。postMessage兼容IE8+、Firefox、Opera、Safari、Chrome。

    需要两个异域的服务器来做测试,当然也可以用本地和线上服务器作为两个异域的服务器。假如使用phonegap开发,就可以将请求文件安装在客户端,然后动态请求服务器的数据处理,获得并显示数据。这样就可以用任意Web开发语言及方法来开发phonegap App所需的后台。

    1.  postMessage的用法

    postMessage是HTML5为解决js跨域问题而引入的新的API,允许多个iframe/window跨域通信。

    假设有结构如下:

    test.html

   


   


   

postMessage (跨域)


   


   


   


   

   

   

   



   


   

目标iframe传来的信息:


   

暂无信息


   

   


   


    iframe.html

    iframe指向xiebiji.com

   


   

   

   

   



   


   

暂无信息。


    下面是test.html里的Javascript代码(发送数据):

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

    document.querySelector(form)。onsubmit=function(e){

    win.postMessage(document.getElementById("message")。value,"*");

    if (e.preventDefault)

    e.preventDefault();

    e.returnValue = false;

    }

    关键代码就一句:

    win.postMessage(document.getElementById("message")。value,"*");

    postMessage是通信对象的一个方法,所以向iframe通信,就是iframe对象调用postMessage方法。postMessage有两个参数,缺一不可。第一个参数是要传递的数据,第二个参数是允许通信的域,“*”代表不对访问的域进行判断,可理解为允许所有域的通信。

    然后是iframe.html里侦听接收数据的代码:

    var parentwin = window.parent;

    window.onmessage=function(e){

    document.getElementById("test")。innerHTML = e.origin + "say:" + e.data;

    parentwin.postMessage(HI!你给我发了"+e.data+"。,"*");

    };

    很简单,相信一看就懂了。e.data包含传送过来的数据,e.origin指代源域。

    然后iframe.html也给test.html发送回应的数据,test.html接收数据。代码雷同,就不贴代码了。

    点此查看Demo

    2. Ajax跨域请求

    基于以上的跨域通信,只要将Ajax代码放在iframe.html里的onmessage处理函数里头,将test.html用postMessage传过来的数据作为参数发送请求,再将返回的数据用postMessage传给test.html。这样就实现了跨域的Ajax请求。其实是很简单的东西。

    贴个示例代码吧,但跟以上的代码无关。

    (function(){

    //获取跨域数据

    window.onmessage = function(e){

    var url = "yangzebo.com/demo/noforget/test.php?msg=" + e.data;

    //Ajax

    var xhr = getXHR();

    if(xhr){

    xhr.open("GET",url,true);

    xhr.onreadystatechange = changeHandle;

    xhr.send(null);

    }else{

    alert("不支持Ajax");

    }

    function changeHandle(){//返回处理

    if(xhr.readyState == 4){

    var parentwin = window.parent;

    parentwin.postMessage(xhr.responseText,"*");//跨域发送数据

    }

    }

    function getXHR(){//获取XMLHttpRequest

    var xhr_temp;

    if(window.XMLHttpRequest){

    xhr_temp = new XMLHttpRequest();

    }else if(window.ActiveXObject){

    xhr_temp = new ActiveXObject("Microsoft.XMLHTTP");

    }else{

    xhr_temp = null;

    }

    return xhr_temp;

    }

    };

    })();

    然后给个不好看的Demo。

    有兴趣代码请求啥的自个用开发人员工具看吧,“zebo男”是从数据库读出来的,“my msg”是sendAndReceive.html发给test.php的Ajax请求的参数,通过test.php和iframeforAjax.html回传到sendAndReceive.html。

    3. 提示

    要获取iframe的contentWindow才能调用postMessage。

    postMessage一定要在iframe加载完成之后调用才可以正常运行。

4000-880-989
(24小时热线)
联系客服
微信公众号

官方公众号

小程序

©2008-2022 CORPORATION ALL Rights Reserved. 昆明奥远科技有限公司版权所有 滇ICP备09003328号-1 滇公网安备 53011102000818号 增值电信业务经营许可证号:滇B2-20110045
昆明那家网络公司好,新媒体运营,网站优化,网络推广,网站建设,网页设计,网站设计,网站推广,云南网站公司,昆明新媒体公司,云南网红主播,昆明SEO公司,昆明网站建设,昆明网络推广,昆明网站优化,昆明网站推广,红河网站建设,大理网络公司,曲靖网络公司,丽江网站设计,昭通网络公司,保山大数据服务,智慧高速建设,智慧校园服务,云南IDC服务商,网络安全测评,等保测评,网站关键词排名优化服务,服务客户尽超2000余家,一切尽在奥远科技,服务电话:13888956730