これが私自身の質問に対する答えです。同じ問題を抱えている人に役立つことを願っています。
まず第一に、通常のアプリ コード (コントローラ、モデルなど) では、ファイル アップロードの進捗イベントを観察できません。メソッドのオーバーライドを破壊することに気付くまで、動作しているように見えた before-filter を使用しようとしました。そのため、進行状況をログに記録し、終了イベントが発生したときに next() を呼び出す req.form の進行状況と終了イベントをリッスンするだけの、独自の非常に単純なミドルウェアを作成する必要がありました。
module.exports = function (compound) {
var express = require('express');
var app = compound.app;
app.configure(function(){
app.use(compound.assetsCompiler.init());
app.use(express.static(app.root + '/public', { maxAge: 86400000 }));
app.set('jsDirectory', '/javascripts/');
app.set('cssDirectory', '/stylesheets/');
app.set('cssEngine', 'less');
app.set('view engine', 'ejs');
app.use(express.bodyParser({
//keepExtensions: true,
limit: 10000000, // 10M limit
defer: true
}));
// Thats the middleware
app.use(function(req, res, next){
// Only use it if form isnt parsed yet through bodyParser
if(!req.form){next();return;}
req.form.on('progress', function(bytesReceived, bytesExpected) {
console.log('progress: '+Math.round(bytesReceived/bytesExpected*100)+'%');
req.form.on('end',function(){
console.log('fileupload finished');
next();
});
});
app.use(express.cookieParser('secret'));
app.use(express.session({secret: 'secret'}));
app.use(express.methodOverride());
app.use(app.router);
});
};
ミドルウェア呼び出しの順序は非常に重要です。最初に bodyParser を呼び出す必要があります ( を使用defer:true
)。これが完了すると、パーサーはすべての受信リクエストを解析し、フォームのみを委任enctype="multipart/form-data"
できます。その後、ミドルウェアはアップロードを監視できます。その後、セッションと Cookie が読み込まれます。現在アップロードしているユーザーがそうする権利を持っているかどうかを知るために、ミドルウェアの前にセッションと Cookie をロードしようとしましたが、非常に有線の動作が発生しました。私はセッションを読むことができ、すべてが素晴らしいように見えますが、フォーム オブジェクトのすべてのデータが 2 倍になりました。{name:'dude'}
メソッドオーバーライド{name:{0:'dude',1:'dude'}}
も破壊するようになりました。この注文は、私が知っている唯一の作業中の注文です。
二重化されたデータに関する前述の問題の解決策がある場合は、どんな助けもいただければ幸いです:)
//編集: 上記の問題の解決策を見つけました。Probem は - もちろんいつものように - ミドルウェアの順序でした。ここでも、アップロードの進行状況とセッションによる認証で機能する「最終的な」コードは次のとおりです。
module.exports = 関数 (複合) {
var express = require('express');
var app = compound.app;
app.configure(function(){
app.use(compound.assetsCompiler.init());
app.use(express.static(app.root + '/public', { maxAge: 86400000 }));
app.set('jsDirectory', '/javascripts/');
app.set('cssDirectory', '/stylesheets/');
app.set('cssEngine', 'less');
app.set('view engine', 'ejs');
// make sure you run `npm install browserify uglify-js`
// app.enable('clientside');
// At the very first load Cookie and Session
app.use(express.cookieParser('secret'));
app.use(express.session({secret: 'secret'}));
// Load the bodyParer then with defer:true
app.use(express.bodyParser({
//keepExtensions: true,
limit: 10000000, // 10M limit
defer: true
}));
// Now comes the own middleware with access to the session _and_ the progress
app.use(function(req, res, next){
console.log('searching for files to upload...');
if(!req.form || req.form.type != 'multipart'){next();return;}
console.log('check if user is autheticated...');
if(!req.session.userId)
{
console.log('user is not authenticated. Throwing Error to prevent further upload!');
try { throw new Error("Stopping file upload..."); }
catch (e) { res.end(e.toString()); }
next();return;
}
console.log('file found - attaching events...');
req.form.on('progress', function(bytesReceived, bytesExpected) {
console.log('progress: '+Math.round(bytesReceived/bytesExpected*100)+'%');
});
req.form.on('end',function(){
console.log('fileupload finished');
next();
});
});
app.use(express.methodOverride());
app.use(app.router);
});
};