文字列化された関数をポストメッセージ イベント データとして渡すことを妨げるものは何もありません。次のような関数宣言の実装は簡単です。
function doSomething(){
alert("hello world!");
}
encodeURI
その文字列の解釈は次のとおりです。
console.log(encodeURI(doSomething.toString()));
//function%20doSomething()%20%7B%0A%20%20%20%20alert(%22hello%20world!%22);%0A%7D
その後、クロージャーの一部として実行できます-過度に想像力に富んだものではありません
eval('('+decodeURI(strCallback)+')();');
クロスフレーム アーキテクチャのないフィドルの概念実証 があります。postMessage バージョンをまとめることができるかどうかを確認しますが、jsfiddle を使用してホストすることは自明ではありません。
アップデート
約束どおり、機能する完全なモックアップ (以下のリンク)。正しいevent.origin
チェックがあれば、これは十分に侵入できないでしょうが、私たちのセキュリティチームがこのように本番環境に入れることは決してないだろうという事実を私は知っていますeval
:)
オプションが与えられた場合、機能を 2 つのページにわたって正規化して、パラメトリック メッセージのみを渡す必要があるようにすることをお勧めします (つまり、関数ではなく引数を渡します)。ただし、これが推奨されるアプローチであるシナリオがいくつかあります。
親コード:
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", 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!");
}
プロトタイプのモックアップ:親コードとiframe コード。