javascript – 如何通过postMessage执行功能

前端之家收集整理的这篇文章主要介绍了javascript – 如何通过postMessage执行功能前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个iframe中的这个代码
window.addEventListener('message',function(e){

  if(e.data == 'test')
    console.log(e);

},false);

而这里面的父文档:

$('#the_iframe').get(0).contentWindow.postMessage('test','http://localhost/');

所以父文档向iframe发送一个“测试”消息,它可以工作.

但是,如何在父文档中定义一个函数,并以某种方式通过postMessage将此函数发送到iframe,这将在本地执行该函数

函数对文档进行了一些更改:

var func = function(){
  $("#some_div").addClass('sss');
}

(#some_div存在于iframe中,而不是父文档)

解决方法

没有什么会阻止你传递一个字符串函数作为postmessage事件数据.对于任何函数声明,实现是微不足道的
function doSomething(){
    alert("hello world!");
}

你可以编码它的字符串解释:

console.log(encodeURI(doSomething.toString()));
//function%20doSomething()%20%7B%0A%20%20%20%20alert(%22hello%20world!%22);%0A%7D

然后它可以作为关闭的一部分执行 – 这不是过分的想象力

eval('('+decodeURI(strCallback)+')();');

有一个fiddle’d proof of concept没有跨架架构 – 我会看看我是否可以放在一起postMessage版本,但是主持w / jsfiddle是不重要的

更新

如所承诺的,一个完整的模型,工作(链接下面).使用正确的event.origin检查,这将是非常透明的,但我知道,我们的安全团队永远不会让eval进行生产,像这样:)

给定选项我建议功能在两个页面之间归一化,这样只需要传递参数消息(即传递参数不是函数);然而,绝对有几种情况,这是首选方法.

代码

document.domain = "fiddle.jshell.net";//sync the domains
window.addEventListener("message",receiveMessage,false);//set up the listener

function receiveMessage(e) {
    try {
        //attempt to deserialize function and execute as closure
        eval('(' + decodeURI(e.data) + ')();');
    } catch(e) {}
}

iframe代码

document.domain = "fiddle.jshell.net";//sync the domains
window.addEventListener("message",false);//set up the listener

function receiveMessage(e) {
    //"reply" with a serialized function
    e.source.postMessage(serializeFunction(doSomething),"http://fiddle.jshell.net");
}

function serializeFunction(f) {
    return encodeURI(f.toString());
}

function doSomething() {
    alert("hello world!");
}

原型模型:parent codeiframe code.

猜你在找的JavaScript相关文章