使用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类上进行解码。