私のアプリのユーザーがMeteorでファイルをダウンロードできるようにする必要があります。現在私がやっているのは、ユーザーがファイルのダウンロードをリクエストしたときです。ファイルの場所とリクエストのタイムスタンプを持つドキュメントをMongoの "fileRequests"コレクションに入れ、新しく作成したリクエストのIDを返します。クライアントが新しいIDを取得すると、すぐにmydomain.com/uploads/:idに行きます。流星が行う前に、私はその要求を傍受するために、このようなものを使用します。Meteor router(NodeJS)でファイルシステムのcreateReadStreamを使用する方法
var connect = Npm.require("connect");
var Fiber = Npm.require("fibers");
var path = Npm.require('path');
var fs = Npm.require("fs");
var mime = Npm.require("mime");
__meteor_bootstrap__.app
.use(connect.query())
.use(connect.bodyParser()) //I add this for file-uploading
.use(function (req, res, next) {
Fiber(function() {
if(req.method == "GET") {
// get the id here, and stream the file using fs.createReadStream();
}
next();
}).run();
});
私はファイル要求が5秒未満前になされたことを確認するためにチェックして、私はすぐに要求文書を削除
私はそれを照会した後。
これはうまくいくと思いますが、安全です(十分)。誰もログインせずにリクエストを行うことはできません.5秒間は、作成されたリクエストURLをハイジャックすることができるかなり小さなウィンドウですが、私のソリューションではまったく気になりません。それは汚いと感じる!
私は同じことを達成するためにMeteor-Routerを使用しようとしました。そうすれば、彼らが世界のトリッキーを5秒間開かずに正しくログインしているかどうかを確認できます。
だからここに私はそれのために書いたコードは次のとおりです。これは素晴らしいですね
Meteor.Router.add('/uploads/:id', function(id) {
var path = Npm.require('path');
var fs = Npm.require("fs");
var mime = Npm.require("mime");
var res = this.response;
var file = FileSystem.findOne({ _id: id });
if(typeof file !== "undefined") {
var filename = path.basename(file.filePath);
var filePath = '/var/MeteorDMS/uploads/' + filename;
var stat = fs.statSync(filePath);
res.setHeader('Content-Disposition', 'attachment; filename=' + filename);
res.setHeader('Content-Type', mime.lookup(filePath));
res.setHeader('Content-Length', stat.size);
var filestream = fs.createReadStream(filePath);
filestream.pipe(res);
return;
}
});
、右のコードの残りの部分とに収まると、何が関与ハッキング読まないのは簡単ですが、!それは動作しません!ブラウザは回転して回転し、何をすべきか分かりません。私はゼロエラーメッセージが表示されます。私は他のタブでアプリを使い続けることができます。私はそれが何をしているのかわからない、それは決して "ロード"を停止しません。サーバーを再起動すると、すべての正しいヘッダーを含む0バイトのファイルが取得されますが、データは取得されません。
何か助けていただければ幸いです。
EDIT:
より少し周り掘り後、私は円形構造エラーにJSONオブジェクトの結果に応答オブジェクトを有効にしようとしていることに気づきました。
ここで興味深いのは、 "データ"イベントのファイルストリームを聞いて、応答オブジェクトを文字列化しようとすると、そのエラーが発生しないということです。しかし、私が最初の解決策( "データ"を聞いて、応答を文字列化する)で同じことをしようとすると、再びエラーが発生します。
したがって、Meteor-Routerソリューションを使用すると、応答オブジェクトに何かが起こっています。私はまた、 "データ"イベントのresponse.finishedにtrueとフラグが立てられていることに気付きました。
filestream.on('data', function(data) {
fs.writeFile('/var/MeteorDMS/afterData', JSON.stringify(res));
});
。私たちは1つには2つの問題があることを知りました。 'return false;'を実行する必要があります。これはhttps://github.com/tmeasday/meteor-router/blob/master/lib/router_server.js#L86でミドルウェアの 'next()'を呼び出しますが、 'pipe () 'も動作しません。私たちはまだ調査中です。 – nalply