1

只是搞乱node.js,我试图让一个文件上传器工作,在客户端对文件进行分块,通过socket.io将片段发送到服务器,然后重新组装。这是一个相当幼稚的实现,但只是试图学习。目前,如果我提交一个文本文件,它会移动并正确重新组合,但如果我尝试上传一个图像文件,编码就会混乱并且文件已损坏。

我在客户端读取二进制字符串,节点 fs 编码设置为二进制。还需要发生什么?

客户代码

while(start < fileSize)
{
    var reader = new FileReader();
    reader.onload = function(e){
        var data = {
            "data" : e.target.result,
            "sequence" : chunkCount++
        };
        socket.emit("sendChunk", data, function(data){
            console.log("Confirmation recieved");
        });
        console.log("Log: Sent");
    };

    reader.onerror = function(e){
        alert(e.getMessage());
    };

    var blob = file.slice(start, end);
    reader.readAsBinaryString(blob);
    start = end;
    end = end + chunkSize;

}

服务器代码

socket.on('sendChunk', function (data) {
    fs.appendFileSync(path + fileName, data.data, 'binary');
    console.log(data.sequence + ' - The data was appended to file ' + fileName);
});

更新

根据给出的建议,我更新了代码以使用 base64 解码。有时仍然会出现一些排序问题,但大多数情况下文件正在正确传输。

客户代码:

var data = {
    "data" : window.btoa(e.target.result),
    "sequence" : chunkCount++
};
socket.emit("sendChunk", data, function(data){
    console.log("Confirmation recieved");
});

服务器代码:

var decoded =  new Buffer(data.data, 'base64').toString('binary');
fs.appendFileSync(path + fileName, decoded, 'binary');
4

1 回答 1

3

socket.emit()是用 JavaScript 编写的,因此将有效负载视为 JavaScript String。您在服务器上收到乱码数据,因为在 JavaScript 中,字符串以 UCS-2 表示,并且某些控制字符正在转义。换句话说:JavaScript 字符串不是Array字节大小的字符,它不适合存储或传输二进制数据。

传输图像最安全的方法是在客户端将二进制数据编码为 base64,并在服务器上使用Buffer 类进行解码。

于 2013-02-18T17:13:41.747 回答