通用Iframe跨域通信库实现

简介: 前言 前端在页面嵌入其他站点的页面时,常常会遇到跨域通信的问题,浏览器为了安全问题,限制了不同域名的JS直接调用。 解决方案 浏览器再限制跨域调用的同时,也预留了一个比较安全的通道。那就是message通道。

前言

前端在页面嵌入其他站点的页面时,常常会遇到跨域通信的问题,浏览器为了安全问题,限制了不同域名的JS直接调用。

解决方案

浏览器再限制跨域调用的同时,也预留了一个比较安全的通道。那就是message通道。 只要得到一个页面的window对象,都可以调用其postMessage的api,而不会有任何限制。而希望接受到其他页面message的页面只需要侦听这一消息即可。
发送者代码示例

var parentWindow = window.parent; //假设这是一个放在iframe的页面,那么这样可以得到其父页面的window对象
parentWindow.postMessage({
           data: 'test'
 }, '*')

侦听者代码示例

window.addEventListener('message', function(event) {

}, false);

经过以上几行简单的代码,就完成一个基本的页面通信了。

写一个通用的通信库

接下来对以上的代码进行改良,使其成为一个通用的iframe通信库。

代理端 iframe-proxy.js的内容

var IFRAME_PROXY = {
    invoke: function(ns, params, callback, source, domain) {
        try {
            var arr = ns.split('.');
            var target = window;
            for (var i = 0; i < arr.length; i++) {
                var t = arr[i]
                target = target[t];
            }
        } catch (error) {
            console.log(ns + 'not found, check your method.');
            return;
        }
        params.success = function(res) {
            source.postMessage({
                'type': 'QN_PROXY_CALLBACK',
                'params': res,
                'callback': callback,
                'code': 200
            }, domain);
        }

        params.error = function(res) {
            source.postMessage({
                'type': 'IFRAME_PROXY_CALLBACK',
                'params': res,
                'callback': callback,
                'code': 999
            }, domain);

        };
        target.invoke(params);
    }
}

window.addEventListener('message', function(event) {
    //console.log('received response:  ', event.data);
    var data = event.data;
    var domain = event.origin;
    var source = event.source;
    switch (data.type) {
        case 'IFRAME_PROXY':
            IFRAME_PROXY.invoke(data.ns, data.params, data.callback, source, domain);
            break;
    }
}, false);

调用端iframe-proxy-client.js

var __sourceWin__ = null;
var __callbackMap__ = {};
window.addEventListener('message', function(event) {
    var data = event.data;
    switch (data.type) {
        case 'IFRAME_PROXY_CALLBACK':
            var fn = data.callback;
            var isSuccess = data.code == 200;
            if (isSuccess) {
                __callbackMap__[fn].success(data.params);
            } else {
                __callbackMap__[fn].error(data.params);
            }
            break;
    }

});

function ___noop() {};
var IFRAME_PROXY = {
    invoke: function(ns, params) {
        var callbackId = 'qnproxy' + new Date().getTime() + Math.floor(Math.random() * 100000) + Math.floor(Math.random() * 100000);
        __callbackMap__[callbackId] = {
            success: params.success || ___noop,
            error: params.error || ___noop
        }
        for (var o in params) {
            if (typeof params[o] == 'function') {
                delete(params[o])
            }
        }
        window.parent.postMessage({
            type: 'IFRAME_PROXY',
            ns: ns,
            params: params,
            callback: callbackId
        }, '*')
    }
}

如何使用

在iframe的的页面引入iframe-proxy-client.js,在父页面引入 iframe-proxy.js, 假设子页面需要调用父页面的方法, Util.getName('abc'),那么调用

IFRAME_PROXY.invoke('Util.getName','abc', function(res) {
  //res就是父页面调用的函数结果
})

经过以上几步,就实现了一个通用了IFRAME通信库。

目录
相关文章
|
4月前
|
安全 前端开发 JavaScript
跨域iframe通信
跨域iframe通信
|
6月前
|
移动开发 前端开发 安全
iframe实现跨域通信的方法
iframe实现跨域通信的方法
186 6
|
6月前
|
JavaScript 前端开发 安全
JavaScript中跨域资源共享(CORS):原理和解决方案
【4月更文挑战第22天】本文介绍了JavaScript中跨域资源共享(CORS)的原理和解决方案。CORS借助HTTP头部字段允许跨域请求,核心是Access-Control-Allow-Origin响应头。解决方案包括:服务器端设置响应头(如使用Express.js的cors中间件)、使用代理服务器或JSONP。现代Web开发推荐使用CORS,因为它更安全、灵活,而JSONP已逐渐被淘汰。理解并正确实施CORS能提升Web应用性能和安全性。
|
6月前
|
JavaScript
iframe 跨域通信和不跨域通信
iframe 跨域通信和不跨域通信
|
前端开发 JavaScript 安全
带你读《现代Javascript高级教程》——前端跨页面通信:实现页面间的数据传递与交互(1)
带你读《现代Javascript高级教程》——前端跨页面通信:实现页面间的数据传递与交互
200 0
|
移动开发 安全 JavaScript
html5使用postMessage解决跨域和跨窗口消息传递的解决方案
html5使用postMessage解决跨域和跨窗口消息传递的解决方案
148 0
|
Web App开发 移动开发 安全
「趣学前端」关于iframe跨域通信
用技术实现梦想,用梦想打开创意之门。之前开发遇到了iframe跨域通信的问题,今天分享一下解决方案,顺便总结一波知识点。
931 1
「趣学前端」关于iframe跨域通信
|
JavaScript
iframe通信案例
vue项目中使用iframe通信的代码示例
166 0
|
Web App开发
Ajax-02:Chrome网络控制台查看通信报文
Ajax-02:Chrome网络控制台查看通信报文
202 0
Ajax-02:Chrome网络控制台查看通信报文