使用socket.io/node.js上传文件块不能处理非文本文件

只是搞乱node.js,我试图得到一个file upload工作,在客户端的文件块,通过socket.io发送件到服务器,并重新组装。 这是一个相当天真的实施,但只是试图学习。 目前,如果我提交一个文本文件,它移动并重新组装正确,但如果我尝试上传说图像文件,编码是搞砸了,文件已损坏。

我在客户端读取二进制string,并将节点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); }); 

更新

根据给出的build议,我更新了代码以使用base64解码。 有时还会出现一些sorting问题,但大部分文件都正确传输。

客户代码:

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

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

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