提问者:小点点

Node.js和Requestjs:将转换流作为文件传输到Request.js以便上传


我正在使用节点存档器(https://github.com/archiverjs/node-archiver)在内存上创建一个zip文件。使用存档器的管道功能,我将所有内容通过管道传输到转换流。如果需要,我可以将此流通过管道传输到文件,但我想让请求(https://github.com/request)读取此流,这样我就不必访问文件系统。

下面,我的转换流被称为bridge。我没有在Transform上做任何特别的事情(我相信它也可能是一个PassThrough流)。

var archive = archiver('zip');
archive.pipe(bridge);
var r = request.post(url, function(err, res, body){ .... }
var form = r.form();
form.append('token', <some token>);
form.append('file', bridge, { "filename" : "package.zip", "contentType" : "application/zip" });
archive.append(<some string>, { "name": <some file name> });
archive.finalize();

这不起作用(文件部分似乎是空的)。然而,如果我将网桥Transform流通过管道传输到文件写入流,并且在流完成后,我在表单文件操作中创建一个对该文件的读流,它就可以工作了。当然,因为现在我有了一个完全格式的文件,request可以读取它(这里我不需要桥,只需要常规的fs流)

bridge.pipe(fs.createWriteStream(<myfile>));
var archive = archiver('zip');
archive.pipe(bridge);
bridge.on("finish", function(){
    var r = request.post(url, function(err, res, body){ .... }
    var form = r.form();
    form.append('token', <some token>);
    form.append('file', fs.createReadStream(<myfile>), { "filename" : "package.zip", "contentType" : "application/zip" });

}
archive.append(<some string>, { "name": <some file name> });    
archive.finalize();

我想知道request是否要求读取流是文件流——以及我在这里还可能做错什么。


共1个答案

匿名用户

我有一个类似的问题,发现问题既不在于nodejs也不在于requestjs。

这是HTTP的一个限制。如果没有已知的内容长度,就无法上传文件,因为只有在转换完成后才能知道内容长度。看到这个:HTTP POST:需要content-length头?

解决这个问题的唯一方法是一次上传带有可读事件的小块。不过,这需要您的目标api允许分块或多部分上传。