我正在一个小型门户网站上工作,当我上传文件(图像)> ~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进行文件上传。