我正在尝试使用一个简单的文件上传机制与Express 4.0一起使用,但我在undefined
正文中req.files
获得了app.post
。以下是相关代码:
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');
});
});
});
答案 0 :(得分:197)
body-parser
模块只处理JSON和urlencoded表单提交,而不是多部分(如果你上传文件就是这种情况)。
对于multipart,您需要使用connect-busboy
或multer
或connect-multiparty
之类的内容(multiparty / formidable是最初在express bodyParser中间件中使用的内容)。还有FWIW,我正在编写一个名为reformed
的busboy上更高级别的层。它配有Express中间件,也可以单独使用。
答案 1 :(得分:14)
以下是我发现谷歌搜索的内容:
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");
});
答案 2 :(得分:10)
看起来body-parser
支持在Express 3中上传文件,但在{4}}
在查看了mscdex的答案中的一些模块之后,我发现no longer included Connect as a dependency是一个更好的选择,也是最接近替换的东西。我注意到的唯一差异在于上传文件的属性。
console.log(req.files)
使用正文解析器(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' } }
答案 3 :(得分:5)
multer是一个处理“multipart / form-data”的中间件,并且神奇地和使请求中的上传文件和表单数据可用作request.files和request.body。
安装multer: - npm install multer --save
<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
});
希望这有帮助!
答案 4 :(得分: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!!!');
});
答案 5 :(得分:1)
请使用以下代码
app.use(fileUpload());
答案 6 :(得分:1)
这个功能需要一个包安装,有很多,但我个人更喜欢“express-fileupload”。只需在终端中通过“npm i express-fileupload”命令安装它,然后在你的根文件中使用它
const fileUpload = require("express-fileupload");
app.use(fileUpload());
答案 7 :(得分:0)
问题已解决!!!!!!!
证明storage
函数DID一次都不会运行。
因为我必须将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');
答案 8 :(得分:0)
只需在上面的答案中添加内容,您就可以简化对express-fileupload
的使用,使其仅用于需要它的单个路由,而不必将其添加到每条路由中。
let fileupload = require("express-fileupload");
...
app.post("/upload", fileupload, function(req, res){
...
});
答案 9 :(得分:0)
我在methodOverride中间件之前添加了multer作为全局中间件, 它也适用于 router.put。
const upload = multer({
storage: storage
}).single('featuredImage');
app.use(upload);
app.use(methodOverride(function (req, res) {
...
}));
答案 10 :(得分:-2)
express-fileupload
看起来像是目前仍在使用的唯一中间件。
使用相同的示例,multer
和connect-multiparty
给出了 req.file 或 req.files 的未定义值,但是{{1工作。
关于 req.file / req.files 的空值,提出了很多问题和问题。