admin管理员组文章数量:1022935
I've read through all the possible answers here but I'm not sure anymore what the problem could be because none of them works. I have one form that uploads a single image and it works as expected but on a different form where I try and upload multiple files and have form inputs, the req.file is always undefined and the image data ends up in the req.body. So somewhere I think maybe there is an issue where multer is not getting the file data...?
I read in a couple of places that body-parser is possibly not playing well with multer but I unfortunately need them both.
route
const destination = './public/uploads/posts';
const storage = multer.diskStorage({
destination: destination,
filename: (req, file, cb) => {
cb(null, file.originalname);
},
});
const upload = multer({storage}).array('images');
router.post('/posts', (req, res) => {
upload(req, res, (err) => {
if(err) {
console.log('errors', err)
res.json({success: false, error: err})
} else {
if(req.files === undefined) {
console.log('error: Images returned undefined');
} else {
const { title, description, url, auth_name, auth_id } = req.body;
if(!title || !description) {
return res.json({
success: false,
error: 'All fields required',
message: 'Title and description fields are required'
});
}
// path we store in the db
let imageLocation = [];
const post = new Post();
for (const file of req.files) {
imageLocation.concat('/uploads/posts/' + file.filename)
}
post.title = title;
post.description = description;
post.url = url;
post.author_name = auth_name;
post.author = auth_id;
post.images = imageLocation;
post.save((err, post) => {
if(err) {
return res.json({ success: false, error: err, message: 'post failed' });
} else {
return res.json({ success: true, message: "added new post", post: post });
}
});
}
}
});
});
post in react ponent
My images are set in state which I get from the DropZone package (I tested without DropZone as well with same results. I made sure the the input name is "images"
submitNewPost = () => {
const { title, description, url, images } = this.state;
const auth_id = this.props.author_id;
const auth_name = this.props.author_name;
const formdata = new FormData();
formdata.append('title', title);
formdata.append('description', description);
formdata.append('url', url);
formdata.append('author_name', auth_name);
formdata.append('author', auth_id);
formdata.append('images', images);
fetch('/api/posts', {
method: 'POST',
body: formdata
}).then(res => res.json())
.then((res) => {
if (!res.success) {
this.setState({ message: res.message });
} else {
this.setState({
title: '',
description: '',
url: '',
images: '',
message: res.message
});
socket.emit('newPost', res.post);
}
});
}
UPDATE
With some help on this thread I managed to upload the images using my existing route and postman. When I test the route using my form, I still get an empty req.file and no uploads.
I added express-multipart-file-parser to my setup and I figure that is what brought me one step closer to fixing this.
Server
This is what I added to my server.js
import { fileParser } from 'express-multipart-file-parser';
app.use(fileParser({
rawBodyOptions: {
limit: '15mb', //file size limit
},
busboyOptions: {
limits: {
fields: 20 //Number text fields allowed
}
},
}));
I've read through all the possible answers here but I'm not sure anymore what the problem could be because none of them works. I have one form that uploads a single image and it works as expected but on a different form where I try and upload multiple files and have form inputs, the req.file is always undefined and the image data ends up in the req.body. So somewhere I think maybe there is an issue where multer is not getting the file data...?
I read in a couple of places that body-parser is possibly not playing well with multer but I unfortunately need them both.
route
const destination = './public/uploads/posts';
const storage = multer.diskStorage({
destination: destination,
filename: (req, file, cb) => {
cb(null, file.originalname);
},
});
const upload = multer({storage}).array('images');
router.post('/posts', (req, res) => {
upload(req, res, (err) => {
if(err) {
console.log('errors', err)
res.json({success: false, error: err})
} else {
if(req.files === undefined) {
console.log('error: Images returned undefined');
} else {
const { title, description, url, auth_name, auth_id } = req.body;
if(!title || !description) {
return res.json({
success: false,
error: 'All fields required',
message: 'Title and description fields are required'
});
}
// path we store in the db
let imageLocation = [];
const post = new Post();
for (const file of req.files) {
imageLocation.concat('/uploads/posts/' + file.filename)
}
post.title = title;
post.description = description;
post.url = url;
post.author_name = auth_name;
post.author = auth_id;
post.images = imageLocation;
post.save((err, post) => {
if(err) {
return res.json({ success: false, error: err, message: 'post failed' });
} else {
return res.json({ success: true, message: "added new post", post: post });
}
});
}
}
});
});
post in react ponent
My images are set in state which I get from the DropZone package (I tested without DropZone as well with same results. I made sure the the input name is "images"
submitNewPost = () => {
const { title, description, url, images } = this.state;
const auth_id = this.props.author_id;
const auth_name = this.props.author_name;
const formdata = new FormData();
formdata.append('title', title);
formdata.append('description', description);
formdata.append('url', url);
formdata.append('author_name', auth_name);
formdata.append('author', auth_id);
formdata.append('images', images);
fetch('/api/posts', {
method: 'POST',
body: formdata
}).then(res => res.json())
.then((res) => {
if (!res.success) {
this.setState({ message: res.message });
} else {
this.setState({
title: '',
description: '',
url: '',
images: '',
message: res.message
});
socket.emit('newPost', res.post);
}
});
}
UPDATE
With some help on this thread I managed to upload the images using my existing route and postman. When I test the route using my form, I still get an empty req.file and no uploads.
I added express-multipart-file-parser to my setup and I figure that is what brought me one step closer to fixing this.
Server
This is what I added to my server.js
import { fileParser } from 'express-multipart-file-parser';
app.use(fileParser({
rawBodyOptions: {
limit: '15mb', //file size limit
},
busboyOptions: {
limits: {
fields: 20 //Number text fields allowed
}
},
}));
Share
Improve this question
edited May 10, 2019 at 9:59
n1stre
6,0964 gold badges23 silver badges42 bronze badges
asked Oct 25, 2018 at 13:20
wind_kindwind_kind
61111 silver badges26 bronze badges
4 Answers
Reset to default 5To properly populate req.files
you need to use formdata.append
like this:
images.forEach(image => {
formdata.append('images', image);
})
thanks for all the help. I managed to fix it. Turns out I was concatenating the FileList object to an array in my state so the structure was all wrong and at the server it just failed. My images upload perfectly now.
If I posted that part of my react ponent, I'm sure any of you would have picked up on that in a second, sorry. Did not occur to me that the problem was further up in my ponent.
THE PROBLEM
onFileLoad = (e) => {
this.setState({
images: this.state.images.concat(e.target.files)
});
}
THE FIX
onFileLoad = (e) => {
this.setState({
images: e.target.files
});
}
submitMediaPOst = () => {
const imageArr = Array.from(images);
imageArr.forEach(image => {
formdata.append('images', image);
});
...
You are missing to pass value with array.
router.post('posts', upload.array('image', 10), function (req, res, next) {
})
for this issue not getting req.file
in controller after upload middleware, while testing in postman select multiple file in single property and of course in front end append the files in a loop
doc.forEach(file=> {
formdata.append('file', file);
}
I've read through all the possible answers here but I'm not sure anymore what the problem could be because none of them works. I have one form that uploads a single image and it works as expected but on a different form where I try and upload multiple files and have form inputs, the req.file is always undefined and the image data ends up in the req.body. So somewhere I think maybe there is an issue where multer is not getting the file data...?
I read in a couple of places that body-parser is possibly not playing well with multer but I unfortunately need them both.
route
const destination = './public/uploads/posts';
const storage = multer.diskStorage({
destination: destination,
filename: (req, file, cb) => {
cb(null, file.originalname);
},
});
const upload = multer({storage}).array('images');
router.post('/posts', (req, res) => {
upload(req, res, (err) => {
if(err) {
console.log('errors', err)
res.json({success: false, error: err})
} else {
if(req.files === undefined) {
console.log('error: Images returned undefined');
} else {
const { title, description, url, auth_name, auth_id } = req.body;
if(!title || !description) {
return res.json({
success: false,
error: 'All fields required',
message: 'Title and description fields are required'
});
}
// path we store in the db
let imageLocation = [];
const post = new Post();
for (const file of req.files) {
imageLocation.concat('/uploads/posts/' + file.filename)
}
post.title = title;
post.description = description;
post.url = url;
post.author_name = auth_name;
post.author = auth_id;
post.images = imageLocation;
post.save((err, post) => {
if(err) {
return res.json({ success: false, error: err, message: 'post failed' });
} else {
return res.json({ success: true, message: "added new post", post: post });
}
});
}
}
});
});
post in react ponent
My images are set in state which I get from the DropZone package (I tested without DropZone as well with same results. I made sure the the input name is "images"
submitNewPost = () => {
const { title, description, url, images } = this.state;
const auth_id = this.props.author_id;
const auth_name = this.props.author_name;
const formdata = new FormData();
formdata.append('title', title);
formdata.append('description', description);
formdata.append('url', url);
formdata.append('author_name', auth_name);
formdata.append('author', auth_id);
formdata.append('images', images);
fetch('/api/posts', {
method: 'POST',
body: formdata
}).then(res => res.json())
.then((res) => {
if (!res.success) {
this.setState({ message: res.message });
} else {
this.setState({
title: '',
description: '',
url: '',
images: '',
message: res.message
});
socket.emit('newPost', res.post);
}
});
}
UPDATE
With some help on this thread I managed to upload the images using my existing route and postman. When I test the route using my form, I still get an empty req.file and no uploads.
I added express-multipart-file-parser to my setup and I figure that is what brought me one step closer to fixing this.
Server
This is what I added to my server.js
import { fileParser } from 'express-multipart-file-parser';
app.use(fileParser({
rawBodyOptions: {
limit: '15mb', //file size limit
},
busboyOptions: {
limits: {
fields: 20 //Number text fields allowed
}
},
}));
I've read through all the possible answers here but I'm not sure anymore what the problem could be because none of them works. I have one form that uploads a single image and it works as expected but on a different form where I try and upload multiple files and have form inputs, the req.file is always undefined and the image data ends up in the req.body. So somewhere I think maybe there is an issue where multer is not getting the file data...?
I read in a couple of places that body-parser is possibly not playing well with multer but I unfortunately need them both.
route
const destination = './public/uploads/posts';
const storage = multer.diskStorage({
destination: destination,
filename: (req, file, cb) => {
cb(null, file.originalname);
},
});
const upload = multer({storage}).array('images');
router.post('/posts', (req, res) => {
upload(req, res, (err) => {
if(err) {
console.log('errors', err)
res.json({success: false, error: err})
} else {
if(req.files === undefined) {
console.log('error: Images returned undefined');
} else {
const { title, description, url, auth_name, auth_id } = req.body;
if(!title || !description) {
return res.json({
success: false,
error: 'All fields required',
message: 'Title and description fields are required'
});
}
// path we store in the db
let imageLocation = [];
const post = new Post();
for (const file of req.files) {
imageLocation.concat('/uploads/posts/' + file.filename)
}
post.title = title;
post.description = description;
post.url = url;
post.author_name = auth_name;
post.author = auth_id;
post.images = imageLocation;
post.save((err, post) => {
if(err) {
return res.json({ success: false, error: err, message: 'post failed' });
} else {
return res.json({ success: true, message: "added new post", post: post });
}
});
}
}
});
});
post in react ponent
My images are set in state which I get from the DropZone package (I tested without DropZone as well with same results. I made sure the the input name is "images"
submitNewPost = () => {
const { title, description, url, images } = this.state;
const auth_id = this.props.author_id;
const auth_name = this.props.author_name;
const formdata = new FormData();
formdata.append('title', title);
formdata.append('description', description);
formdata.append('url', url);
formdata.append('author_name', auth_name);
formdata.append('author', auth_id);
formdata.append('images', images);
fetch('/api/posts', {
method: 'POST',
body: formdata
}).then(res => res.json())
.then((res) => {
if (!res.success) {
this.setState({ message: res.message });
} else {
this.setState({
title: '',
description: '',
url: '',
images: '',
message: res.message
});
socket.emit('newPost', res.post);
}
});
}
UPDATE
With some help on this thread I managed to upload the images using my existing route and postman. When I test the route using my form, I still get an empty req.file and no uploads.
I added express-multipart-file-parser to my setup and I figure that is what brought me one step closer to fixing this.
Server
This is what I added to my server.js
import { fileParser } from 'express-multipart-file-parser';
app.use(fileParser({
rawBodyOptions: {
limit: '15mb', //file size limit
},
busboyOptions: {
limits: {
fields: 20 //Number text fields allowed
}
},
}));
Share
Improve this question
edited May 10, 2019 at 9:59
n1stre
6,0964 gold badges23 silver badges42 bronze badges
asked Oct 25, 2018 at 13:20
wind_kindwind_kind
61111 silver badges26 bronze badges
4 Answers
Reset to default 5To properly populate req.files
you need to use formdata.append
like this:
images.forEach(image => {
formdata.append('images', image);
})
thanks for all the help. I managed to fix it. Turns out I was concatenating the FileList object to an array in my state so the structure was all wrong and at the server it just failed. My images upload perfectly now.
If I posted that part of my react ponent, I'm sure any of you would have picked up on that in a second, sorry. Did not occur to me that the problem was further up in my ponent.
THE PROBLEM
onFileLoad = (e) => {
this.setState({
images: this.state.images.concat(e.target.files)
});
}
THE FIX
onFileLoad = (e) => {
this.setState({
images: e.target.files
});
}
submitMediaPOst = () => {
const imageArr = Array.from(images);
imageArr.forEach(image => {
formdata.append('images', image);
});
...
You are missing to pass value with array.
router.post('posts', upload.array('image', 10), function (req, res, next) {
})
for this issue not getting req.file
in controller after upload middleware, while testing in postman select multiple file in single property and of course in front end append the files in a loop
doc.forEach(file=> {
formdata.append('file', file);
}
本文标签: javascriptreqfile is undefined for multiple file uploadsStack Overflow
版权声明:本文标题:javascript - req.file is undefined for multiple file uploads - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745579899a2157246.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论