NodeJS/Express 在发送标头后无法设置标头 当我上传文件时出错



我正在一个小型门户网站上工作,当我上传文件(图像)> ~25kb时,我遇到了一个错误。我已经测试了这个系统,它在小图像上工作得很好,但是当我尝试大图像时,一切都崩溃了。

我使用的是最新版本的node, express 3.4.0, multer 0.0.7,这里是有问题的代码:

服务器:

var express = require('express'),
    multer = require('multer'),
    api = require('./routes/api.js'),
    http = require('http'),
    path = require('path'),
    app = express(),
    server = http.createServer(app);

app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.set('port', process.env.VCAP_APP_PORT || 7000);
app.use(multer({dest: __dirname + '/uploads/'}))
app.use(app.router);
app.configure(function()
    app.use("/uploads",express.static(__dirname + '/uploads'));
    app.post('/api/upload/file', api.upload);
    app.use(function(err, req, res, next) {
        if(!err) return next();
        console.log(err.stack);
        res.json({error: true});
    });
    app.use(multer({
        dest:'./uploads/',
         rename: function (fieldname, filename) {
            return filename.replace(/W+/g, '-').toLowerCase();
        }
    }));
});
server.listen(app.get('port'), function(){
    console.log('Express server listening on port ' + app.get('port'));
});

和api。上传功能:

exports.upload = function(req, res) {
    console.log("Upload");
    var resumeName = null,
        picName = null;
    console.log("File: " + JSON.stringify(req.files));
    if(req.files.resume.size >= 0 || req.files.pic.size >= 0) {
        if(req.files.resume.size > 0) {
            resumeName = req.files.resume.name;
        }
        if(req.files.pic.size > 0) {
            picName = req.files.pic.name;
        }
        console.log("Got file");
    }
    console.log("sending...");
    res.send({picName: picName, resumeName: resumeName});
}

如果它有帮助的话,我的前端是angular的,我正在使用reangular和ng-upload来帮助提交和上传文件。

您正在app.configure()内部配置应用程序

app.configure(function()
    app.use("/uploads",express.static(__dirname + '/uploads'));
    app.post('/api/upload/file', api.upload);
    app.use(function(err, req, res, next) {
        if(!err) return next();
        console.log(err.stack);
        res.json({error: true});
    });
    app.use(multer({
        dest:'./uploads/',
         rename: function (fieldname, filename) {
            return filename.replace(/W+/g, '-').toLowerCase();
        }
    }));
});

和外部

app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.set('port', process.env.VCAP_APP_PORT || 7000);
app.use(multer({dest: __dirname + '/uploads/'}))
app.use(app.router);
注意,您已经两次定义了multer中间件。

我猜multer必须在app.use(app.router)之前定义。第二个定义是在报头已经发送之后再发送。

注意: app.configure()已被弃用,甚至在express 4.x中开始被删除。我不推荐使用它。您最好在外部定义所有中间件。

TL;DR在服务器上保存上传文件时存在(相当于)竞争情况。单独上传文件修复了这个问题。

我最终听从了@Leonel的建议,搬到了connect-busboy。一开始我也有同样的问题,后来我意识到发生了什么。我在前端使用ng-upload,但ng-upload会一次上传所有文件。由于我使用的表单有两个用户可以上传的(可选的)文件,因此后端上传服务将被req.files中的两个文件击中。由于我的multer实现并没有很好地计划这一点,它将尝试处理这两个,但只发送一个响应(它会首先到达res.send行)。

为了解决这个问题,我移动到angular-file-upload,它允许我在如何上传文件(将单独上传)上有更多的选项。此外,我还使用了safwanc的解决方案来使用connect-busboy进行文件上传。

相关内容

  • 没有找到相关文章

最新更新