I am sending post request with FormData .but when I checked on node server my body is blanked why ?
I do the following steps
let formData = new FormData();
// add one or more of your files in FormData
// again, the original file is located at the `originFileObj` key
formData.append("file", values['Temp_id_card'].fileList[0].originFileObj);
formData.append("Emp No",values['Emp No'].toLowerCase())
formData.append("Remarks",values['Remarks'])
formData.append("UpdatedStatus",values['Status'])
formData.append("id",id)
formData.append("Att Date",attDate)
send data like that
export const sendPostRequest1 = (url, data, config = {}) => {
let updatedConfig = {
headers: {Authorization: `Bearer ${getAuthToken()}` || ""},
...config
};
return axios.post(url, data, updatedConfig);
}
when i checked on network tap it shows data is send
but When debug on node server it shows empty body why ?
Node js code
var Storage = multer.diskStorage({
destination: function(req, file, callback) {
if(req.user.userId === req.body.userId){
callback(null, "./Images");
}else {
throw new AuthenticationError("Unauthorized User");
}
},
filename: function(req, file, callback) {
callback(null, file.fieldname + "_" + Date.now() + "_" + file.originalname);
}
});
var upload = multer({
storage: Storage
}).array("file", 1); //Field name and max count
router.post('/upload', (req, res) => {
upload(req, res, function(err) {
if (err) {
return res.end("Something went wrong!");
}
return res.end("File uploaded successfully!.");
});
});
when I checked on this if(req.user.userId === req.body.userId){ line req.body is empty object ?
I also added this my middleware
app.use(bodyParser.json({ limit: "100mb"}));
app.use(bodyParser.urlencoded({ limit: "50mb",extended: false }));
app.use(requestLogger);
app.use(helmet());
Fetched the same issue(Angular+NodeJs), and solved by the help of middleware.
Just write
router.post('/upload', upload.single('file'), (req, res, next) => {
instead of
router.post('/upload', (req, res) => {
For more details
Related
I have array with buffer files. I have been trying upload buffers to express server using multer for whole day.
Problem is my files pass by req.body.image. But multer finds files from req.files. Multer can't found files and alerted error. How fix this problem?
Front End code:
let UserPhoto = ["data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUNDX1BST0ZJTEUAAQEAAAIYAAAAAAQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAA"];
let formData = new FormData();
for (let i = 0; i < userPhoto.length; i++) {
formData.append("files", userPhoto[i]);
}
axios
.post(`v0/photo/${id}/User`, formData, {
headers: { "Content-Type": "multipart/form-data" },
})
.then((result) => {
console.log(result);
})
.catch((error) => {
console.log(error);
}
Back End code:
const fileFilter = (req, file, cb) => {
if (file.mimetype.substr(0, 6) === "image/") {
cb(null, true);
} else cb(new ErrorCatcher("Зөвхөн зураг upload хийнэ үү.", 400), false);
};
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, director);
},
filename: (req, file, cb) => {
cb(null, Date.now() + "." + file.mimetype.split("/")[1]);
},
});
const upload = multer({
storage: storage,
limits: { fileSize: process.env.IMAGE_MAX_SIZE },
fileFilter: fileFilter,
});
//authorize,
// permission("user", "operator", "manager", "admin"),
router
.route("/:objectId/:objectType")
.post(upload.array("files", 8), createImageConnect);
I was using formData. Result was same.
I am trying to create a route through which I can upload photos. However as I made so,e changes it stopped working and I am not sure how to make it work.
const multer = require('multer');
// MULTER STORAGE
const multerStorage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, '/upload');
},
filename: (req, file, cb) => {
const ext = file.mimetype.split('/')[1];
// Saving format: user-UserId-DateStamp.ext
//e.g user-608d55c7e512b74ee00791de-1621992912638.jpeg
cb(null, `user-${req.body.userId}-${Date.now()}.${ext}`);
},
});
//MULTER FILTER
const multerFilter = (req, file, cb) => {
//mimetype always starts with image/ then png or jpeg or..
if (file.mimetype.startsWith('image')) {
cb(null, true);
} else {
cb(new AppError('You are only allowed to upload image files.', 400), false);
}
};
const uploadDirectory = multer({
storage: multerStorage,
fileFilter: multerFilter,
});
//exports.uploadPhoto = uploadDirectory.single('photo');
//app.use(express.static('./uploads'));
// INCLUDE ERROR CLASS AND ERROR CONTROLLER
const AppError = require('../utils/appError.js');
const errorController = require('./errorController.js');
const { Mongoose } = require('mongoose');
The main problem Im guessing is in this block
//UPLOAD PHOTO
exports.uploadPhoto = uploadDirectory(async (req, res) => {
console.log(req.body);
console.log(req.file);
try {
const newPhoto = await photoModel.create(req.file);
newPhoto.save().then((result) => {
console.log('Saved');
res.status(201).json({
status: 'success',
// data: JSON.parse(JSON.stringify(newPhoto.file)),
});
});
} catch (err) {
console.log('Error in upload');
errorController.sendError(err, req, res);
}
}).single('photo');
Can anybody let me know how to correctly write the exports.uploadPhoto
Originally the last function looked like this
exports.uploadPhoto = async (req, res) => {
console.log(req.body);
console.log(req.file);
try {
const newPhoto = await photoModel.create(req.file);
newPhoto.save().then((result) => {
console.log('Saved');
res.status(201).json({
status: 'success',
// data: JSON.parse(JSON.stringify(newPhoto.file)),
});
});
} catch (err) {
console.log('Error in upload');
errorController.sendError(err, req, res);
}
};
The multer middleware function, in your case uploadDirectory, is usually used before other middleware functions/controllers where you have your business logic (e.g. uploadPhoto).
app.post('/upload', uploadDirectory.single('photo'), uploadPhoto);
Keep your original uploadPhoto function and with the above code you'll have access to the data and file through reg.body and req.file, respectively.
This Request Parsing in Node.js Guide (it's free) will help you with file uploads in Node.js.
I am trying to send an image in a POST req from react to nodejs. However my back-end is not receiving the file and req.file is undefined. When I test the server image upload code with postman, everything works fine so I suspect something is wrong on the front-end. Anybody know what's wrong?
Here's my code:
Image_Upload.js (submit image func, fileList[0] is an image):
onSubmitImage = e => {
const config = {
headers: {
"content-type": "multipart/form-data"
}
};
const formData = new FormData();
formData.append(
"image",
this.state.fileList[0]
);
axios
.post("/api/profile/img_upload", formData)
.then(res => console.log("Response: " + res))
.catch(err => console.log(err.response.data));
};
profile.js (receiving image endpoint):
router.post(
"/img_upload",
passport.authenticate("jwt", { session: false }),
(req, res) => {
upload(req, res, err => {
console.log(req);
if (err) {
res.status(400).json({ Error: err });
} else {
if (req.file == undefined) {
res.status(404).json({ error: "no file selected" });
} else {
res.json({ fileLoc: req.file.location });
}
}
});
}
);
img_upload.js (multer setup):
const upload = multer({
storage: storage,
limits: { fileSize: 1000000 },
fileFilter: function(req, file, cb) {
checkFileType(file, cb);
}
}).single("image");
Any help is appreciated
EDIT:
I am noticing that when nodejs receives the req from the front-end, it is in req.body instead of req.file. So I am positive the problem is in react. How can I get react to send it as req.file instead of req.body?
Image request from Reacdt Front-end to Nodejs backend
upload that you defined is actually an express middleware which must take 3 arguments: request, response and next, respectively. next() calls the subsequent middleware in case no errors or next(error) otherwise. I highly recommend checking the answers to this question to get a better idea.
What you have done here is that you're calling a middleware as if it was a method. To fix that, config multer first
const multer = require('multer');
const upload = multer({
storage: 'path/here/',
limits: { fileSize: 1000000 },
fileFilter: function(req, file, cb) {
checkFileType(file, cb);
}
});
then
router.post("/img_upload",
passport.authenticate("jwt", { session: false }),
upload.single('image'),
(req, res) => {
// Your code here
});
I am trying to understand how routing works with express.
With some code redacted, I have the following in my server.js
const multer = require("multer"); //for uploading image
const bodyParser = require("body-parser"); //for adding employee(below)
app.get("/employees/add", (req, res) => {
res.sendFile(path.join(__dirname, './views', 'addEmployee.html'));
});
app.get("/images/add", (req, res) => {
res.sendFile(path.join(__dirname, './views', 'addImage.html'));
});
app.get("/employees", (req, res) => {
data.getAllEmployees().then((data) => {
res.json(data);
}).catch(function(err) {
console.log("An error was encountered: " + err);
});
});
app.get("/images", (req, res) => {
let imagePath = './public/images/uploaded';
fs.readdir(imagePath, function(err, items) {
if (items.length == 0) {
console.log("No images");
res.send("Error reading images directory<br/><h3>Return to <a href='/'><em>HOME</em></a></h3>");
} else {
//res.json(items);
var finalString = "Images: " + JSON.stringify(items) + "<br/><h3>Return to <a href='/'><em>HOME</em></a></h3>";
res.send(finalString);
}
});
});
const storage = multer.diskStorage({
destination: "./public/images/uploaded",
filename: function (req, file, cb) {
cb(null, Date.now() + path.extname(file.originalname));
}
});
const upload = multer({ storage: storage });
app.use(express.static("./public/images/uploaded"));
app.post("/add-image", upload.single("imageFile"), (req, res) => {
const formFile = req.file;
res.send("<p>Your submission >> " + JSON.stringify(formFile) + " was successful</p><br/><h3>Return to <a href='/'><em>HOME</em></a></h3>");
});
My data-service.js has a function defined as,
module.exports.addEmployee = function(employeeData) {
return new Promise((resolve, reject) => {
(typeof employeeData.isManager === 'undefined') ? false : true;
employeeData.employeeNum = employees.length + 1;
employees.push(employeeData);
resolve(employees);
});
}
Where the employees array resides in an employees.json file.
I have no issues getting the uploading images working. It uploads, and sends me back a response. Now, I am trying to get Adding a New Employee to work with body-parser, however I am running into a few issues.
My server.js waits for:
app.get("/employees/add", (req, res) => {
res.sendFile(path.join(__dirname, './views', 'addEmployee.html'));
});
And then redirects to my addEmployee.html which has the action, action="/add-employee", redirecting back to my server.js with the route,
app.post("/add-employee", (req, res) => {
//do something
});
I have tried calling it with something along the lines of,
app.post("/add-employee", (req, res) => {
data.addEmployee();
//etc
});
having defined addEmployee as in the second code snippet.
And this, (obviously, otherwise I wouldnt be here lol), doesn't quite work. I feel like, although syntax may be an issue, I am misconstruing the routing logic here. What am I missing?
Currently, I am using multer library to save files on File system. This application is using Node and Express.
I can save the file first on server and then encrypt it. Later on delete the unencrypted file. However, I do not want to add unencrypted file on server directly. So, I am looking for a way to encrypt the incoming file from the front end and then save it to disk.
const defaultFolder = 'upload';
const filePath = resolveHome(process.env.FILE_STORAGE_LOCATION || defaultFolder);
const key = 'test';
const cipher = crypto.createCipher('aes-256-cbc', key);
const decipher = crypto.createDecipher('aes-256-cbc', key);
const upload = multer({
storage: multer.diskStorage({
destination: filePath,
filename: (req, file, cb) => {
const parts = file.originalname.split('.');
const ext = parts.pop();
const name = parts.join('.');
cb(null, name + '-' + Date.now() + '.' + ext);
},
}),
}).single('file');
app.post('/upload', (req, res) => {
upload(req, res, err => {
if (err) {
return res.status(400).send({
error: 'The request was invalid',
fileName: req.file.originalname,
});
}
return res.status(200).send({
fileName: req.file.filename,
});
});
});
I tried to use crypto library to encrypt the file but it's not working. I believe the req.cipher is invalid as I would normally use req.file to get reference to the file.
app.post('/upload', (req, res) => {
upload(req, res, err => {
output = fs.createWriteStream(filePath + '/' + req.file.originalname);
req.pipe(cipher).pipe(output).on('finish', () => console.log('Encrypted file written on disk'));
if (err) {
return res.status(400).send({
error: 'The request was invalid',
fileName: req.file.originalname,
});
}
return res.status(200).send({
fileName: req.file.originalname,
});
});
});
I had tried to just write file without using cipher and file was empty. Adding this information in case it helps.
req.pipe(output).on('finish', () => console.log('Encrypted file written on disk'));
Can you try this
app.post('/upload', function(req, res) {
upload(req, res, function(err) {
var fileName = req.file.destination +"\\"+ req.file.filename
var input = fs.createReadStream(fileName);
var output = fs.createWriteStream(fileName + ".enc");
input.pipe(cipher).pipe(output);
output.on('finish', function() {
fs.unlink(fileName, (err) => {
if (err) throw err;
console.log('Encrypted file written to disk!');
res.end('Encrypted file written to disk!')
});
});
})
})