Node.js 和 Requestjs:通过管道将转换流作为文件上传到 Request.js

Node.js and Requestjs: Pipe a Transform stream to Request.js as a file for upload

我正在使用 node-archiver ( https://github.com/archiverjs/node-archiver ) 在内存中创建一个 zip 文件。 使用存档程序的管道功能,我将所有内容都通过管道传输到转换流。 如果需要,我可以将此流通过管道传输到文件,但我想让 Request ( 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();

这不起作用(似乎 file 部分是空的)。但是,如果我将我的桥接转换流通过管道传输到文件写入流——并且在流完成之后——我在表单文件操作中为该文件创建了一个读取流,它就可以工作。当然,因为现在我有一个完整的文件并且 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 是否要求读取流是文件流——还有什么地方我可能做错了。

我有类似的问题,发现问题既不是nodejs也不是requestjs。

这是 HTTP 的限制。您无法上传内容长度未知的文件,在转换完成之前,您无法从转换中获知该长度。看到这个:

解决此问题的唯一方法是使用可读事件一次上传小块。不过,这需要您的目标 api 允许分块或分段上传。