首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >上传- compoundjs/express中使用bodyParser的进度({defer:true})失败

上传- compoundjs/express中使用bodyParser的进度({defer:true})失败
EN

Stack Overflow用户
提问于 2013-05-07 08:23:29
回答 1查看 897关注 0票数 1

我试图找出如何正确地使用在express (和compoundjs)中使用的bodyParser的延迟属性。目标是获得对事件属性的访问,该属性应该是可能的,将延迟属性传递给bodyParser。

发生的情况是,bodyParser对enctype=multipart/form-data根本不起作用。在我看来,bodyParser仍然应该解析请求并将所有相关数据放在body对象中。但是,当我使用一个带有enctype=multipart/ form的表单时,body对象是空的。这会导致一些错误,如authetification failureforgery-Check

所以-怎么回事?我发现有什么不对劲吗?bodyParser应该做好它的工作,我想要访问进度事件。

PS:我读到了使用bodyParser、sessionParser等命令导致的错误。因此,这是我的配置(compoundjs):

代码语言:javascript
复制
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');
    // make sure you run `npm install browserify uglify-js`
    // app.enable('clientside');
    app.use(express.methodOverride());
    app.use(express.cookieParser('secret'));
    app.use(express.session({secret: 'secret'}));
    app.use(express.bodyParser({
            //keepExtensions: true,
            limit: 10000000, // 10M limit
            defer: true
    }));
    app.use(app.router);
});

};
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-05-07 20:12:15

这是我自己问题的答案。我希望它能帮助人们解决同样的问题。

首先:你不能在你的正常应用程序代码(例如控制器,模型)中观察到文件的进程-事件。我试着使用之前的过滤器,这似乎是有效的,直到我意识到它破坏了方法-复述。这就是为什么我必须编写自己的非常简单的中间件,它只监听req.form的进度和结束事件,后者记录进度,并在结束事件发生时调用next()。

代码语言:javascript
复制
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"的形式委托给您。然后,您的中间件可以观察上传。在那次会议之后,Cookies就被加载了。我试图在中间件之前加载会话和cookie,以了解当前上载的用户是否有权这样做,但这会导致非常有线的行为。我可以阅读这个会话,这一切看起来都很棒,但是我在表单对象中的所有数据都翻了一番。{name:'dude'}表示{name:{0:'dude',1:'dude'}}也破坏了该方法-重写。这是我唯一知道的工作顺序。

如果您有解决上述双倍数据问题的方法,请提供任何帮助:)

//编辑:我找到了上述问题的解决方案。Probem和往常一样是中间件的顺序。在这里,“最终”代码与通过会话上传进度和身份验证一起工作:

module.exports =函数(复合){

代码语言:javascript
复制
    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);
    });

};
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16414473

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档