我需要在主页和嵌入的
iframe
之间传递大量数据。
为了避免[反]序列化开销,我希望将 ArrayBuffer
与 postMessage()
一起传递,并在不同的 iframe
中实例化指向此缓冲区的视图。
但这种方法似乎行不通,因为
postMessage()
的 MDN 文档将 message
参数描述为:
要发送到另一个窗口的数据。使用结构化克隆算法对数据进行序列化。
这似乎表明传递“指针”是不可能的,因为
postMessage()
有效地仅传递字符串......
有解决办法吗?在主线程和工作线程之间传递“可传输对象”效果很好。将 ArrayBuffer
传递给
node.js本机扩展的 C/C++ 代码也是如此。
HTML
<button id="send">Send Message</button>
<iframe id="receiver" src="receiver.html" width="500" height="200"></iframe>
var receiver = document.getElementById('receiver').contentWindow;
var hugeData = '';
var hugeDataLen = 10000003;
var messagePartSize = 500;
function generateHugeData(){
var i = 0;
console.log(hugeDataLen / messagePartSize);
for(i=0;i<Math.floor(hugeDataLen/messagePartSize);i++){
hugeData += randomString(messagePartSize);
}
if(hugeDataLen>(messagePartSize*i)){
hugeData += randomString(hugeDataLen-(messagePartSize*i));
}
}
sendBigMessage = function(e) {
var messagePart = '';
var i = 0;
for(var i = 0; i < Math.floor(e.length/messagePartSize); i++) {
messagePart = e.substr(i*messagePartSize,messagePartSize);
receiver.postMessage({mydata: JSON.stringify(messagePart), len: e.length}, 'http://localhost:10080');
}
if(hugeDataLen>(messagePartSize*i)){
console.log(hugeDataLen-(messagePartSize*i));
messagePart = e.substr(i*messagePartSize,hugeDataLen-(messagePartSize*i));
receiver.postMessage({mydata: JSON.stringify(messagePart), len: e.length}, 'http://localhost:10080');
}
};
function randomString(len) {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < len; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
var btn = document.getElementById('send');
function sendMessage(e) {
sendBigMessage(hugeData)
}
btn.addEventListener('click', sendMessage);
generateHugeData();
console.log(hugeData);
HTML
<div id="message"></div>
var data = '';
window.onload = function() {
var messageEle = document.getElementById('message');
function receiveMessage(e) {
if (e.origin !== "http://localhost:10080")
return;
messageEle.innerHTML = messageEle.innerHTML + e.data.mydata;
var jsonData = JSON.parse( e.data.mydata);
console.log(jsonData);
data += jsonData;
if (data.length === e.data.len) {
alert('complete');
console.log(data);
}
}
window.addEventListener('message', receiveMessage);
}
objects 来做到这一点。你必须像这样调用 postMessage:
iframeElement.contentWindow.postMessage(buffer, { transfer: [buffer] });