图像文件因websocket文件传输而损坏

image files corrupt with websocket file transfer

本文关键字:文件 损坏 传输 websocket 图像      更新时间:2024-01-13

我正在使用websockets进行文件传输,当我下载文件时,我正在按原样接收数据,但当我打开图像文件时,它已损坏。数据文件下载良好,代码如下。

try {
    fileEntry = fs.root.getFile(filename, { create : creat_file });
    var byteArray = new Uint8Array(data.data.length);
    for (var i = 0; i < data.data.length; i++) {
        byteArray[i] = data.data.charCodeAt(i) & 0xff;
    }
    BlobBuilderObj = new WebKitBlobBuilder();
    BlobBuilderObj.append(byteArray.buffer);
    if (!writer) {
        writer = fileEntry.createWriter();
        pos = 0;
    }
    //self.postMessage(writer.position);
    writer.seek(pos);
    writer.write(BlobBuilderObj.getBlob());
    pos += 4096;
    }
catch (e) {
    errorHandler(e);
}

看起来像是从WebSocket中以字符串形式读取数据,将其转换为Blob,然后将其写入文件。

如果您可以控制WebSocket服务器,那么最好的方法是将数据作为二进制帧而不是UTF-8文本数据发送。如果你能让服务器以二进制帧的形式发送数据,那么你就可以告诉WebSocket以Blob的形式传递数据:

ws.binaryType = "blob";
ws.onmessage = function (event) {
    if (event.data instanceof Blob) {
        // event.data is a Blob
    } else {
        // event.data is a string
    }
}

如果这不是一个选项,并且您只能从服务器发送文本帧,那么在从服务器发送之前,您需要将二进制数据编码为文本,然后在另一端解码文本。如果您尝试通过WebSockets直接将二进制数据作为文本帧发送,那么执行charCodeAt(x) && 0xff将导致数据损坏。

例如,您可以在服务器上对数据进行base64编码,然后在客户端中对数据进行base64解码:

ws.onmessage = function (event) {
    raw = window.atob(event.data);
}

更新

webstockify中包含一个性能非常好的纯Javascript base64解码/编码。它可以解码为0-255之间的数字数组,但如果你需要的话,可以很容易地修改为返回字符串(免责声明:我制作了webstockify)。