Ale*_*lex 10 javascript jquery postmessage
我在iframe中有这个代码:
window.addEventListener('message', function(e){
if(e.data == 'test')
console.log(e);
}, false);
Run Code Online (Sandbox Code Playgroud)
这在父文档中:
$('#the_iframe').get(0).contentWindow.postMessage('test', 'http://localhost/');
Run Code Online (Sandbox Code Playgroud)
因此父文档向iframe发送"测试"消息并且它可以正常工作.
但是如何在父文档中定义一个函数,并以某种方式通过postMessage将此函数发送到iframe,iframe将在本地执行该函数?
该函数对文档进行了一些更改,如下所示:
var func = function(){
$("#some_div").addClass('sss');
}
Run Code Online (Sandbox Code Playgroud)
(#some_div存在于iframe中,而不是父文档中)
o.v*_*.v. 14
没有什么可以阻止您将字符串化的函数作为postmessage事件数据传递.对于任何函数声明,实现都是微不足道的
function doSomething(){
alert("hello world!");
}
Run Code Online (Sandbox Code Playgroud)
你可以用encodeURI它的字符串解释:
console.log(encodeURI(doSomething.toString()));
//function%20doSomething()%20%7B%0A%20%20%20%20alert(%22hello%20world!%22);%0A%7D
Run Code Online (Sandbox Code Playgroud)
然后它可以作为闭包的一部分执行 - 这不像是过于富有想象力
eval('('+decodeURI(strCallback)+')();');
Run Code Online (Sandbox Code Playgroud)
在没有跨框架架构的情况下,有一个小提琴的概念证明 - 我会看看我是否可以组合一个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) {}
}
Run Code Online (Sandbox Code Playgroud)
iframe代码:
document.domain = "fiddle.jshell.net";//sync the domains
window.addEventListener("message", receiveMessage, 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!");
}
Run Code Online (Sandbox Code Playgroud)
Ber*_*rgi 10
你不能真的.虽然postMessage的(草案)规范讨论了结构化对象,例如嵌套对象和数组,JavaScript值(字符串,数字,日期等)和某些数据对象,例如File Blob,FileList和ArrayBuffer对象大多数浏览器只允许字符串(当然包括JSON).在MDN或dev.opera上阅读更多内容.但我很确定发送函数对象是不可能的,至少不能作为保留其范围的闭包.
所以,你在字符串化的功能,并结束eval()它在iframe中,如果你真的想从父窗口执行一些代码.但是,我认为任何申请都没有理由允许评估任意代码(即使是来自注册域名); 最好是构建一个消息API,它可以接收(JSON-)字符串命令并调用自己的方法.