在iframe之间传递ArrayBuffer是否可行?

4
我需要在主页面和内嵌iframe之间传递大量的数据块。为避免[de]序列化开销,我想使用postMessage()传递ArrayBuffer,并在不同的iframe中实例化指向这个缓冲区的视图。
但是,MDN文档对postMessage()的描述中,message参数如下:
“要发送到其他窗口的数据。使用结构化克隆算法序列化数据。”
这似乎表明,传递“指针”是不可能的,因为 postMessage() 实际上只传递字符串...
有什么变通方法吗?在主线程和工作线程之间传递可转移对象非常有效。将ArrayBuffer传递给C/C++代码的node.js本地扩展也可以正常工作。

Can you share your code - Ferhat BAŞ
在同一域的情况下,直接分配给 parent.varnameiframe.contentWindow.varname 等不就可以了吗?然后使用 postMessage() 向目标窗口发送消息,通知它读取 varname 即可。 - Compl Yue
1个回答

0

您可以将消息分为两部分发送,每个消息都必须包含数据和长度。当发送消息完成后,您可以在其他地方使用它。同时,如果您的数据量很大,建议使用线程而不是“for”循环来处理代码。

发送者

HTML

<button id="send">Send Message</button>
<iframe id="receiver" src="receiver.html" width="500" height="200"></iframe>

Javascript

    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);
}

Ferhat, 感谢您详细的回答,但这并不能避免序列化/反序列化...我希望有一种方法可以将“C指针”传递给ArrayBuffer,以便可以直接从不同的上下文访问底层数据,而无需复制... - Boris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接