zoukankan      html  css  js  c++  java
  • [HTML5_WebWorkers]利用HTML5的window.postMessage实现跨域通信


    由于同源策略的限制,JavaScript跨域的问题,一直是一个颇为棘手的问题,为了解决js的跨域,web开发人员是煞费苦心,研究了各种跨域方案,如果有机会的话,明河以后会一一展示给各位,今天明河重点介绍下html5新引入的postMessage跨域方案。

    1.哪些场景要考虑跨域问题?

    明河这二周在处理淘宝添加收藏夹的重构,里面就有一个非常经典的跨域问题。

    添加收藏弹出层外层是淘宝商城页面域名是tmall.com,而弹出层内部的页面域名却是taobao.com,接下来的问题就是我现在希望弹出层内部的高度改变了,父页面弹出层的高度也随之改变,同时子iframe内有办法使用一个按钮,关闭父页面的弹出层。
    这个场景还是非常经典的,很多朋友估计多多少少都会遇到这个情况,就是有个弹出层里面嵌一个iframe,iframe内的子页面如何操作父页面的弹出层或其他元素?

    2.淘宝商城是如何处理跨域的?

    由于今天主要是讲html5的跨域方案,这里明河简要提一下,有机会跟大家详细分享。
    淘宝商城有个专门用于处理跨域的js类TMall.XDomain,这个类会生成子iframe中生成一个新的iframe,这个iframe我们叫它代理iframe,代理iframe必须跟父页面时同域的,这样代理iframe就有权限处理父页面。
    这里明河推荐阅读以下文章:

    3.哪些情况下存在跨域问题?

    4.HTML5的window.postMessage简述

    postMessage是html为了解决跨域通信,特别引入的一个新的API,目前支持这个API的浏览器有:Firefox, IE8+, Opera, Safari, Chrome。postMessage允许页面中的多个iframe/window的通信,postMessage也可以实现ajax直接跨域,不通过服务器端代理。

    感谢苏河哥哥提供另外个主机作为跨域测试,O(∩_∩)O哈!
    在上面的demo中,明河简单演示了postMessage的用法,父页面中有二个不同域的iframe,现在我们要求这二个iframe每过一秒,向对方的内容层传递一行文字,对象一接收到文字就开始输出。

    5.postMessage用法解析

    这里以iframe1.html的代码为例。

    1)向另外一个iframe发送消息


    var message = ‘hello,RIA之家!   ‘ + (new Date().getTime());
    window.parent.frames[1].postMessage(message, ‘*’);

    iframe1.html需要向iframe2.html发送消息,也就是第二个iframe,所以是window.parent.frames[1],如果是向父页面发送消息就是window.parent
    postMessage这个函数接收二个参数,缺一不可,第一个参数即你要发送的数据,第二个参数是非常重要,主要是出于安全的考虑,一般填写允许通信的域名,这里明河为了简化,所以使用’*',即不对访问的域进行判断。

    2)另外一个iframe监听消息事件

    iframe2.html中写个监听message事件,当有消息传到iframe2.html时就会触发这个事件。

    var onmessage = function(e) {
    var data = e.data,p = document.createElement(‘p’);
    p.innerHTML = data;
    document.getElementById(‘display’).appendChild(p);
    };
    //监听postMessage消息事件
    if (typeof window.addEventListener != ‘undefined’) {
    window.addEventListener(‘message’, onmessage, false);
    } else if (typeof window.attachEvent != ‘undefined’) {
    window.attachEvent(‘onmessage’, onmessage);
    }

    整个通信过程就结束了!是不是非常简单惬意!
    如果你有加域名限,比如下面的代码:

    window.parent.frames[1].postMessage(message, ‘http://www.36ria.com’);

    就要在onmessage中追加个判断:

    if(event.origin !== http://www.36ria.com’) return;

    6.明河结语

    html5的postMessage相当强悍和易用!你可以利用这个特性解决大部分场景下的跨域问题,不用再创建个代理iframe之类的繁琐方法。严重推荐大家练习下该方法,目前的确存在浏览器差异问题,但相信以后会成为主流跨域通信方案。

  • 相关阅读:
    Transfer: Javascript实现网页水印(非图片水印)
    VirtualPathUtility class from MSDN
    深入理解Flink 系统内部消息传递的exactly once语义
    深入理解Flink EndtoEnd ExactlyOnce语义
    深入理解Flink Metrics的内部结构
    深度优化sql 查询, 提升性能一百倍是什么概念?
    asp.net mvc+asp.net webform: a way of RIA + RAD
    使用scheduled task, 让电脑音乐伴你入眠
    A small breaking change in IE8 causing big pain in the ass: the default type of button element
    tsql 和 clr 的性能实测比对
  • 原文地址:https://www.cnblogs.com/webapplee/p/3818723.html
Copyright © 2011-2022 走看看