2

node-archiver ( https://github.com/archiverjs/node-archiver ) を使用してメモリ上に zip ファイルを作成しています。アーカイバーのパイプ機能を使用して、すべてを Transform ストリームにパイプします。必要に応じて、このストリームをファイルにパイプできますが、リクエスト ( 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、そしてここで他に何が間違っている可能性があるのでしょうか。

4

1 に答える 1

1

私は同様の問題を抱えており、問題がnodejsにもrequestjsにもないことを発見しました。

これは HTTP の制限です。既知のコンテンツの長さがないと、ファイルをアップロードすることはできません。これは、変換が完了するまで変換から知ることができません。これを参照してください: HTTP POST: content-length ヘッダーが必要ですか?

これを回避する唯一の方法は、readable イベントを使用して一度に小さなチャンクをアップロードすることです。ただし、これにはターゲット API でチャンクまたはマルチパート アップロードを許可する必要があります。

于 2016-07-22T18:36:24.690 に答える