I try to send image, some text in form data and I try to console.log(req.body) It's always return {} I've read many topic about this
here is my route/index.js
const express = require('express');
const router = express.Router();
const bodyParser = require('body-parser');
router.use(bodyParser.urlencoded({extended:true}));
router.use(bodyParser.json());
router.route('/').post(AdminController.list);
I tryo to add urlencoded but it still not working .
bodyParser cannot handle multipart/form-data
Try Multer, From official docs:
Multer is a node.js middleware for handling multipart/form-data, which
is primarily used for uploading files. It is written on top of busboy
for maximum efficiency
Multer adds a body object and a file or files object to the request
object. The body object contains the values of the text fields of the
form, the file or files object contains the files uploaded via the
form.
See a working example:
const Multer = require('multer');
const multer = Multer({
storage: Multer.memoryStorage(),
limits: {
fileSize: 5 * 1024 * 1024 // no larger than 5mb, you can change as needed.
}
});
app.post('/upload', multer.single('file'), (req, res) => {
// req.body will contain the text fields, if there were any
fs.createWriteStream('./uploads/' + req.file.originalname)
var fileWriteStream = fs.createWriteStream(req.file.originalname);
fileWriteStream.on('finish', () => {
console.log('file saved successfully');
res.send({ message: 'file saved successfully' })
})
fileWriteStream.end(req.file.buffer)
})
Related
I'm trying to build a service that allows me to upload files I started with single-file uploading but I have an issue when I try to upload multiple files.
In short, my problem is that if I want to upload more than one image, it appears in the storage folder and I don't see the records in my DB.
Example of single-file upload record
Example of multi-file upload record
But those files are saved on my storage
There are two function in multer:
For single file to upload use:
upload.single('avatar')
For multiple file to upload use:
upload.array('photos', 12) //here 12 is max number of files to upload.
Refer to the following sample code:
const express = require("express");
const multer = require("multer");
const app = express();
const multerStorage = multer.memoryStorage();
// Filter files with multer if you need
const multerFilter = (req, file, cb) => {
if (file.mimetype.startsWith("image")) {
cb(null, true);
} else {
cb("upload only images.", false);
}
};
const upload = multer({
storage: multerStorage,
fileFilter: multerFilter,
});
app.post('/singleUpload', upload.single('avatar'), function (req, res,
next) {
// req.body will hold the text fields, if there were any
console.log(req.file);//req.file is the `avatar` file. here avatar is
input field name
})
app.post('/multipleUpload', upload.array('photos', 12), function (req,
res, next) {
// req.body will contain the text fields, if there were any
// req.files is array of `photos` files.here avatar is
input field name
console.log(req.files);
})
Multer receives the Form Data, but leaves all fields, including the image files, in the req.body object. Here is my code:
React:
const state = {
// other fields
images: [], // array of image files
};
let formData = new FormData();
// append other fields
formData.append("images", state.images);
await fetch(url, {
body: formData,
// config
});
Express:
const express = require("express");
const router = express.Router();
const controller = require("./controller");
const multer = require("multer");
const storage = multer.memoryStorage();
const imageFilter = (req, file, cb) => {
// accept image files only
if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/i)) {
return cb(new Error("Only image files are allowed!"), false);
}
cb(null, true);
};
const upload = multer({ storage, fileFilter: imageFilter });
// other routes
router.post("/", upload.array("images"), controller.handleImagePost);
Multer doesn't parse the Form Data files if they are nested in an array. It's best to loop over your React state array, and append each file individually to the formData object. (See FormData API and Multer docs)
for (const image of state.images) {
formData.append("image", image, image.path);
}
Make sure to match the form data field name in your multer middleware code
router.post("/", upload.array("image"), controller.handleImagePost);
I'm new to web dev so sorry if this is sully question. I'm building a webapp that can upload a zip file along with some form data.
On the client side I'm using axios and here is a segment of the code:
handleSubmitClick = (e) => {
console.log(this)
e.preventDefault();
const formData = new FormData();
formData.append('uploaded_file',this.state.file)
formData.append('studyID',this.state.studyID)
formData.append('modality',this.state.modality)
const config = {
headers: {
'Content-Type': 'multipart/form-data'
}
}
return post('/test_post', formData, config)
}
On the backend api side, I'm using Express with Multer middleware to receive the file:
import express from 'express';
import cors from 'cors';
var bodyParser = require('body-parser')
var multer = require('multer');
var upload = multer({ dest: 'uploads/' })
const path = require('path');
const initializeExpress = (): void => {
const app = express();
app.use(cors());
app.use(express.json());
// app.use(express.urlencoded());
app.use(express.urlencoded({ extended: true }));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'build')));
app.post('/test_post', upload.single('uploaded_file'), function (req, res){
console.log('---------- post test_post ----------')
console.log("req.body: ", req.body)
console.log('--------------------------------')
return res.send('pong');
})
app.listen(process.env.PORT || 3000);
};
initializeExpress();
When select a zip file and click a "send" button on the webpage, I can see the following console log on the Express backend api side:
---------- post test_post ----------
req.body: [Object: null prototype] {
studyID: '123qwe',
modality: 'CT'
}
--------------------------------
The form data studyID and modality are received correctly. Since these two form data are automatically extracted from the selected file, I can confirm that the file is selected with no problem. (this.state.file indeed points to the right file object)
However, the uploaded_file field is an empty string and there is a file uploads/ folder:
- uploads
3b3b93d6c2db52ff6d66d60d0315d7fc
The original file selected was testfile.zip, but this file has unknown format and a random name.
How can I fix it?
The original file selected was testfile.zip, but this file has unknown
format and a random name.
What you need is to control the file's name and extension. You can do it using storage option
You can replace this line:
var upload = multer({ dest: 'uploads/' });
by:
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/') // where files will be saved
},
filename: function (req, file, cb) {
cb(null, file.originalname) // using the file's original name
}
})
const upload = multer({ storage: storage })
I'm creating a video upload API in Node.js. To upload it, I have to handle the multipart request, so I'm using npm library "multer".
Try to send a video file(like below) in Postman.
テスト_test.mp4
"テスト" is some Japanese character. And when posting that, the result is:
console.log(req.file.originalname)
=> ƹ�(_test.mp4
I want
originalname=>テスト_test.mp4
not
originalname=>ƹ�(_test.mp4
Implementation:
const express = require('express')
const router = express.Router()
const request = require('request')
const multer = require('multer')
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "some/dest/dir")
}
})
var upload = multer({
storage: storage
}).single("file")
router.use(upload)
router.post("/videos", functinon(req, res, next){
console.log(req.file.originalname)
})
Postman:
・request header Content-Type: multipart/form-data
・request body file:テスト_test.mp4
Does anybody have ideas?
I want to send a images folder along with the other data. (name and openingHours);
this is my vuejs code that I use to submit data to the backend
const formData = new FormData();
formData.append("name", this.name);
formData.append("openingHours", this.openingHours);
formData.append("photos", this.selectedFile);
await this.$http.post("spa", formData);
Here my controller code
var multer = require('multer')
var upload = multer({ dest: 'uploads/' })
router.post('/', upload.array('photos', 10), async (req, res) => {
console.log(req.file);
console.log(req.body);
});
Here the req.file is undefined and photos also come under the body and also this openingHours is not an array. I pass and array in the front-end.
This is my body parser settings in the app.js
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json());
Can anybody tell me what's wrong with my code?
I want to pass openingHours as an JS array.
UPDATED
this is what I get if I console log openingHours in that method.
You need to stringify your array calling JSON.stringify before saving to FormData:
formData.append("openingHours", JSON.stringify(this.openingHours));
And on the backend you need to parse it calling JSON.parse:
const openingHours = JSON.parse(req.body.openingHours)