postMessage与postMessage跨域

HTML5学堂今日postMessage跨域教学流程

先为大家讲解postMessage的基本知识

之后,我们书写一个实例:使用静态的iframe,实现A域前端页面与B域前端页面之间的数据传递

最后,我们使用JS动态的生成iframe,实现A域的前端页面与B域的前端页面“互通”,并在B域中使用AJAX申请B域的后台数据

1 postMessage通信的方法与事件

postMessage的跨域方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。

想要完成“一个域”与“另一个域”的通信,最少需要两个步骤,其一是发送消息,其二是接收消息。在postMessage的这种跨域方式当中,提供了一个postMessage方法和一个message事件。

postMessage方法用于发送消息。

message事件,用于监听是否有消息传递,如果有则执行事件。

2 postMessage方法基本语法

postMessage(message, targetOrigin)方法接受两个参数

2.1 message:要传递的数据。

可以传递任意基本类型或可复制的对象,但IE9-只支持字符串类型的参数。

解决办法:在传递参数的时候需要使用JSON.stringify()方法对对象参数序列化。

2.2 targetOrigin:字符串参数

该参数用于指明目标窗口的源,协议+主机+端口号[+URL],URL会被忽略,所以可以不写

如果希望信息可以传递给任意窗口,可以将参数设置为"*"。

如果要指定和当前窗口同源,可以将参数设置为"/"。

3 message事件的常用属性

事件的属性存在于什么地方呢?事件的各类属性都存储在参数当中。

data:消息

origin:消息来源地址

source:源DOMWindow对象

4 postMessage实现跨域的核心知识

4.1 需要使用到iframe标签(依赖于iframe标签实现A——>B,B——>A的数据交互),A域与B域通过iframe标签构建成父子级关系

4.2 使用postMessage方法进行信息的发送

4.3 使用message事件进行“信息发送”的监听和数据(信息)的接收

5 postMessage实例开发 - 静态iframe申请B域文件

需求:A域中的前端页面向B域中的前端页面发送数据并取回B对A发送的数据。

流程图

用这张来辅助一下对postMessage流程的理解吧~

HTML5学堂-图解:B域的html文件是通过iframe标签引入到A域中;蓝色部分为A域的html文件要执行的功能;橙色部分为B域的html文件要执行的功能。

A域中的a.html的代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>HTML5学堂 - postMessage - 静态iframe实例 - 父级页面</title>
</head>
<body>
    <div id="h5course">A域 - HTML5学堂</div>
    <div>
        <iframe id="child" src="http://lsLib.com/lsLib.html"></iframe>
    </div>


    <script type="text/javascript">
        var h5course = document.getElementById('h5course');


        window.onload=function(){
            window.frames[0].postMessage('data','http://B域.com');
        }


        window.addEventListener('message', function(e){
            var message = e.data;
            h5course.innerHTML = message + '堡堡';
        }, false);
    </script>
</body>
</html>

代码解析:代码的16~18行,表示向B域发送数据,而20~22行表示监听B域发回的数据并进行解析操作。

B域中的b.html文件的代码

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>HTML5学堂 - postMessage - iframe子页面</title>
</head>
<body>
    <!-- B域 -->
    <script type="text/javascript">
        window.addEventListener('message', function(e){
            if(e.source != window.parent) {
                return;
            }
            var childData = 'iframe中的内容';
            window.parent.postMessage(childData, '*');
        }, false);
    </script>
</body>
</html>

代码解析:代码第10行的监听器,表示监听A域发送过来的数据,而11~13行用于保证数据来自“定义的域”。15行表示接收到A域数据之后,再向A域发送数据(即给个“回馈”)。

6 postMessage实例开发 - 动态iframe申请B域后台数据

需求:希望A域中能够访问到B域中的后台数据

A域中的a.html的代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>HTML5学堂 - postMessage - 动态iframe实例</title>
</head>
<body>
    <!-- A域 - 父级页面 -->
    <script src="js/jquery-1.8.3.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        function addIframe() {
            var newIframe = '<iframe id="newframe" src="http://chennb.duapp.com/chennb.html" name="postframe" style="width:0; height:0;position:absolute;left:-9999px;top:0;" />';
            $('body').append(newIframe);


            $('#newframe').on('load', function() {
                $('#newframe')[0].contentWindow.postMessage('ok', 'http://B域.com');
                window.addEventListener('message', function(e) {
                    console.log('利利: ' + e.data);
                }, false);
            });
        } addIframe();
    </script>
</body>
</html>

代码解析:第12~13行代码,代表动态生成iframe标签,并将iframe标签放置于body当中。第14行代码表示,当iframe标签加载完毕之后执行相应功能。第16行代码,表示调用iframe包含页面(contentWindow表示iframe所在的window对象)的postMessage方法发送字符串“ok”,并规定只接收http://B域名下传过来的数据。第17行代码代表监听B域中传回的数据并进行处理。

B域中的b.html文件的代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>HTML5学堂 - postMessage - 动态iframe实例</title>
</head>
<body>
    <!-- B域 - 子级页面 -->
    <script src="js/jquery-1.8.3.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        window.addEventListener('message', function(e){
            $.ajax({
                url: 'http://B域.com/h5course.php',
                type: 'GET',
                success: function(data) {
                    console.log('堡堡: ' + e.data);
                    e.source.postMessage(data, 'http://A域.com/');
                }
            });
        }, false);
    </script>
</body>
</html>

代码解析:第11行代表监听message事件,当接收到A域传递过来的数据时,则执行AJAX功能。第16~17行表示:当AJAX成功返回数据之后,将数据回传给A域。

7 小结

7.1 postMessage的消息发送方式,包括postMessage方法以及message事件;

7.2 postMessage方法中拥有两个参数,分别用于传递数据以及限制数据来源;

7.3 message事件用于监听是否存在postMessage,通过postMessage方法传递过来的所有信息都储存在message事件的参数中;

7.4 实现跨域的基本要求是,A域中包含B域,A域向B域,通过postMessage方法发送数据,B域进行数据监听,收到之后进行数据的处理操作;之后B域再通过postMessage方法发送数据到A域,A域进行数据监听,收到数据处理即可;

7.5 无论使用静态iframe还是动态生成iframe标签,均可以完成A域与B域数据的交互

7.6 可以实现A域的前端页面与B域的前端页面进行数据传递;

7.7 可以与AJAX相结合,实现A域前端页面与B域的前端页面进行数据传递,并控制B域通过AJAX访问B域的后台。

HTML5小编-利利&堡堡 耗时10.5h

原文发布于微信公众号 - HTML5学堂(h5course-com)

原文发表时间:2016-05-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏互联网杂技

前端知识普及之页面加载

如果大家想继续看下面的内容的话,有一个要求,就是回答我一个问题: 你这样写过代码吗? window.onload = function(){ $(".g...

3519
来自专栏mySoul

中止请求和超时 跨域的HTTP请求 认证方式 JSONP

作为同源策略的一部分,XMLHttpRequest对象可以发起HTTP请求,由于同源的影响,导致必须是同源的,

1122
来自专栏软件测试经验与教训

XSS漏洞总结

同源策略 影响源的因素:host,子域名,端口,协议 a.com通过以下代码:

1512
来自专栏大史住在大前端

javascript基础修炼(6)——前端路由的基本原理

现代前端开发中最流行的页面模型,莫过于SPA单页应用架构。单页面应用指的是应用只有一个主页面,通过动态替换DOM内容并同步修改url地址,来模拟多页应用的效果,...

1263
来自专栏张戈的专栏

解决WordPress升级4.2后调用国外图片导致大量404请求的问题

前几天就收到 WordPress 官方发来的预更新通知,告诉我本周会更新到 4.2。果然,昨天就收到了更新推送消息,随手就点击升级了,前台打开看了下没有看到明显...

35310
来自专栏玩转JavaEE

MongoDB副本集配置

上篇文章我们搭建了MongoDB副本集的环境,验证了数据已经可以成功的复制,本文我们就来看看MongoDB副本集的其他操作。 ---- 环境准备 三台服务器,地...

3035
来自专栏Crossin的编程教室

Python 实战(6):放开那只海豹

有了一堆数据后,现在可以把影片详细页面做得更详细一点了。 首先能想到的,就是加上影片的海报。在从豆瓣获取的数据里,有一项 image,就是影片海报图片的地址。如...

3307
来自专栏前端说吧

SASS环境搭建及HBuilder中sass预编译配置

3756
来自专栏数据科学学习手札

(数据科学学习手札50)基于Python的网络数据采集-selenium篇(上)

  接着几个月之前的(数据科学学习手札31)基于Python的网络数据采集(初级篇),在那篇文章中,我们介绍了关于网络爬虫的基础知识(基本的请求库,基本的解析库...

1504
来自专栏技术博客

ExtJs九(ExtJs Mvc用户管理之一)

首先要做的是为用户信息创建一个模型,在Scripts\app\model目录下创建一个名为User.js的文件,然后添加以下模型定义代码:

992

扫码关注云+社区