0

Blob通过 XHR2 将多个分块的文件发送到 Node.js/Express 服务器。

如何在确保它们正确组合的同时在服务器上接收它们?当“一次”上传多个文件时,按照正确的顺序和正确的文件。

以下是我到目前为止的代码(前端和后端),但还没有考虑到多次上传。

前端:

// 'files' is of type FileList, directly from file input.
for (var i = 0, length = files.length; i < length; i++) {
    var file = files[i];

    var bytes = 51200; // 50 KB
    var size = file.size;
    var start = 0;
    var end = bytes;

    while (start < size) {
        sendBlob(file.slice(start, end), file.name, file.type);
        start = end;
        end = start + bytes;
    }   
}   

// sendBlob()
var sendBlob: function (data, filename, filetype) {
    var xhr = new XMLHttpRequest();
    xhr.open('POST', this.url, false);
    xhr.setRequestHeader('X_FILENAME', filename);
    xhr.setRequestHeader('Content-Type', filetype);
    xhr.send(data);
};

后端:

app.post('/', function (req, res) {
    var body = '';
    req.on('data', function (data) {
        body += data;
    });
    req.on('end', function () {
        var filename = req.headers['x_filename'];
        var newPath = __dirname + '/upload/' + filename;
        fs.writeFile(newPath, body, function (err) {
            res.send({
                filename: filename
            });
        });
    });
});

非常小的文本文件可以正确存储,但图像似乎总是被弄乱并最终得到更大的文件大小。更大的文本文件被正确写入,但第一个块似乎丢失了。

4

1 回答 1

0

您的上传逻辑很幼稚。以下是您应该做的一些事情来确保正确性:

  1. 您必须在客户端和服务器之间维护和通信块 ID/编号,以便维护顺序。

    var sendBlob: function (data, filename, filetype, chunkid)
    //set chunkid in header or in data.
    
  2. 在您的服务器中,您接受任何发布请求并将其附加到正文中。您应该维护文件名和文件类型的变量,并在附加之前将其与传入请求匹配。

    Files[Name] = { //Create a new Entry in The Files Variable for each new file
        Filetype : "",
        FileSize: 0,//size of Data in buffer  
        Data: "",  //buffer for storing data
        Downloaded:  //chunks recieved
    }
    

    仅在检查时附加到数据。(额外的文件大小可能是由于这个原因)

  3. 在您fs.writeFile应该将编码设置为二进制,图像和视频文件是二进制编码的,并且将它们写入默认的 utf-8 编码可能会损坏它们。

    fs.writeFile(newPath, body, 'binary', function (err){...});
    
  4. (可选)对于服务器接收到的每个块,它应该向客户端发送一个确认,以便它知道哪个块被丢弃并且必须发送。

于 2013-03-20T06:49:11.480 回答