使用 Express 4.0 上传文件:req.files undefined
Posted
技术标签:
【中文标题】使用 Express 4.0 上传文件:req.files undefined【英文标题】:File uploading with Express 4.0: req.files undefined 【发布时间】:2014-05-31 14:48:35 【问题描述】:我正在尝试获得一个与 Express 4.0 一起使用的简单文件上传机制,但我在 app.post
正文中不断收到req.files
的undefined
。以下是相关代码:
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
//...
app.use(bodyParser( uploadDir: path.join(__dirname, 'files'), keepExtensions: true ));
app.use(methodOverride());
//...
app.post('/fileupload', function (req, res)
console.log(req.files);
res.send('ok');
);
.. 以及随附的 Pug 代码:
form(name="uploader", action="/fileupload", method="post", enctype="multipart/form-data")
input(type="file", name="file", id="file")
input(type="submit", value="Upload")
解决方案
感谢下面mscdex 的回复,我已经改用busboy
而不是bodyParser
:
var fs = require('fs');
var busboy = require('connect-busboy');
//...
app.use(busboy());
//...
app.post('/fileupload', function(req, res)
var fstream;
req.pipe(req.busboy);
req.busboy.on('file', function (fieldname, file, filename)
console.log("Uploading: " + filename);
fstream = fs.createWriteStream(__dirname + '/files/' + filename);
file.pipe(fstream);
fstream.on('close', function ()
res.redirect('back');
);
);
);
【问题讨论】:
如何处理多个文件? @chovy 它应该适用于多个文件 我认为可以做 app.post('/fileupload',busboy(), function(req, res) 很好的解决方案我只想注意,您必须在应用的主目录中创建一个./files/
目录,否则上传后会出现错误。
临时文件是如何处理的? busboy 会自动删除它们吗?在保存到磁盘之前,我只是没有看到任何临时文件被删除。
【参考方案1】:
body-parser
模块仅处理 JSON 和 urlencoded 表单提交,而不是多部分(如果您正在上传文件,则会出现这种情况)。
对于多部分,您需要使用类似 connect-busboy
或 multer
或 connect-multiparty
的东西(multiparty/formidable 是最初在 express bodyParser 中间件中使用的)。同样是 FWIW,我正在 busboy 之上的更高级别的层上工作,称为 reformed
。自带Express中间件,也可以单独使用。
【讨论】:
谢谢,成功了。虽然我不得不使用connect-busboy
而不仅仅是busboy
。用解决方案更新了我原来的帖子。
谢谢伙计!我发现connect-multiparty
选项最好!
reformed
还在开发中吗?您在 github 上的最后一次提交是从 2014 年开始......顺便说一下,在您看来,处理多部分表单数据的最佳模块是什么?我所说的“最佳”是指最好的支持和更好的工作(更少的错误),具有更多的功能和更长的未来。我选择multer
,因为它似乎是最好的支持,但我仍然认为它应该更多支持。
[编辑:没关系,刚刚看到下面的答案。] 在 express 3.0 中使用 multipart,然后在 4.0 中中断?我问是因为本教程使用 3.4.8 并且可以上传文件而不需要任何额外的中间件blog.robertonodi.me/simple-image-upload-with-express
@thetrystero 您链接到的特定示例的 github 存储库实际上已将依赖项签入存储库。如果您深入研究这些依赖项,您将看到 Express 3.x 以及 Connect 2.x(它仍然捆绑了一个多部分模块)。这就是为什么多部分处理“开箱即用”的原因。【参考方案2】:
这是我在谷歌上搜索的结果:
var fileupload = require("express-fileupload");
app.use(fileupload());
这是非常简单的上传机制
app.post("/upload", function(req, res)
var file;
if(!req.files)
res.send("File was not found");
return;
file = req.files.FormFieldName; // here is the field name of the form
res.send("File Uploaded");
);
【讨论】:
对于大文件来说太慢了【参考方案3】:1) 确保您的文件确实是从客户端发送的。例如,您可以在 Chrome 控制台中检查它: screenshot
2) 下面是 NodeJS 后端的基本示例:
const express = require('express');
const fileUpload = require('express-fileupload');
const app = express();
app.use(fileUpload()); // Don't forget this line!
app.post('/upload', function(req, res)
console.log(req.files);
res.send('UPLOADED!!!');
);
【讨论】:
【参考方案4】:看起来body-parser
确实支持在 Express 3 中上传文件,但在 no longer included Connect as a dependency
在查看了 mscdex 答案中的一些模块后,我发现 express-busboy
是一个更好的选择,也是最接近直接替代的方法。我注意到的唯一区别在于上传文件的属性。
console.log(req.files)
使用 body-parser (Express 3) 输出一个如下所示的对象:
file:
fieldName: 'file',
originalFilename: '360px-Cute_Monkey_cropped.jpg',
name: '360px-Cute_Monkey_cropped.jpg'
path: 'uploads/6323-16v7rc.jpg',
type: 'image/jpeg',
headers:
'content-disposition': 'form-data; name="file"; filename="360px-Cute_Monkey_cropped.jpg"',
'content-type': 'image/jpeg' ,
ws:
WriteStream /* ... */ ,
size: 48614
与使用 express-busboy(Express 4)的console.log(req.files)
相比:
file:
field: 'file',
filename: '360px-Cute_Monkey_cropped.jpg',
file: 'uploads/9749a8b6-f9cc-40a9-86f1-337a46e16e44/file/360px-Cute_Monkey_cropped.jpg',
mimetype: 'image/jpeg',
encoding: '7bit',
truncated: false
uuid: '9749a8b6-f9cc-40a9-86f1-337a46e16e44'
【讨论】:
【参考方案5】:multer 是一个中间件,它处理“multipart/form-data”并神奇地将上传的文件和表单数据以 request.files 和 request.body 的形式提供给我们。
安装 multer :- npm install multer --save
在 .html 文件中:-
<form method="post" enctype="multipart/form-data" action="/upload">
<input type="hidden" name="msgtype" value="2"/>
<input type="file" name="avatar" />
<input type="submit" value="Upload" />
</form>
在 .js 文件中:-
var express = require('express');
var multer = require('multer');
var app = express();
var server = require('http').createServer(app);
var port = process.env.PORT || 3000;
var upload = multer( dest: 'uploads/' );
app.use(function (req, res, next)
console.log(req.files); // JSON Object
next();
);
server.listen(port, function ()
console.log('Server successfully running at:-', port);
);
app.get('/', function(req, res)
res.sendFile(__dirname + '/public/file-upload.html');
)
app.post('/upload', upload.single('avatar'), function(req, res)
console.log(req.files); // JSON Object
);
希望这会有所帮助!
【讨论】:
【参考方案6】:请使用下面的代码
app.use(fileUpload());
【讨论】:
var fileupload = require("express-fileupload"); app.use(fileupload());【参考方案7】:此功能需要安装包,其中有很多,但我个人更喜欢“express-fileupload”。只需在终端中通过“npm i express-fileupload”命令安装它,然后在你的根文件中使用它
const fileUpload = require("express-fileupload");
app.use(fileUpload());
【讨论】:
【参考方案8】:问题已解决!!!!!!!
原来storage
函数甚至没有运行一次。
因为我必须将app.use(upload)
包含为upload = multer(storage).single('file');
let storage = multer.diskStorage(
destination: function (req, file, cb)
cb(null, './storage')
,
filename: function (req, file, cb)
console.log(file) // this didn't print anything out so i assumed it was never excuted
cb(null, file.fieldname + '-' + Date.now())
);
const upload = multer(storage).single('file');
【讨论】:
【参考方案9】:只是为了添加到上面的答案,您可以将 express-fileupload
的使用简化为仅需要它的单个路由,而不是将其添加到每个路由。
let fileupload = require("express-fileupload");
...
app.post("/upload", fileupload, function(req, res)
...
);
【讨论】:
【参考方案10】:我在 methodOverride 中间件之前添加了 multer 作为全局中间件, 它也可以在 router.put 中使用。
const upload = multer(
storage: storage
).single('featuredImage');
app.use(upload);
app.use(methodOverride(function (req, res)
...
));
【讨论】:
【参考方案11】:强大的:
const formidable = require('formidable');
app.post('/api/upload', (req, res, next) =>
const form = formidable( multiples: true );
form.parse(req, (err, fields, files) =>
if (err)
next(err);
return;
res.json( fields, files );
);
);
https://www.npmjs.com/package/formidable
【讨论】:
【参考方案12】:express-fileupload
看起来是目前唯一仍在使用的中间件。
在同一个示例中,multer
和 connect-multiparty
给出了未定义的 req.file 或 req.files 值,但 express-fileupload
有效。 p>
还有很多关于req.file/req.files的空值的疑问和问题。
【讨论】:
以上是关于使用 Express 4.0 上传文件:req.files undefined的主要内容,如果未能解决你的问题,请参考以下文章
使用express的bodyParser上传文件,请问如何设置文件大小
在 Express 路由器中使用 multer 进行文件上传