Hi I am trying to upload a file from fronend to backend using multer
Front End
var formData = new FormData();
formData.append("files", image[0]);
formData.append("data", JSON.stringify({status: 'ACK', message: "You are fu*ked"});
return http.axios
.post(apiUrl + apiDomain + "/createAnnouncement", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
})
.then((res) => res);
Backend
const bodyParser = require("body-parser");
const Express = require("express");
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, config.get("announcemnt_upload_file_storage"));
},
filename: function (req, file, cb) {
cb(null, file.filename + "_" + Date.now());
},
});
var upload = multer({ storage: storage });
const Router = Express.Router();
Router.route("/createAnnouncement").post(
upload.single("files"),
(req , resp, next) => {
console.log(" >>>>>>>", req.file);//THis returns undefined
console.log(">>>>", req.files);//This returns undefined
resp.send("Siccess")
}
);
Below is my Req snapshot
Its not getting uploaded to storage and its returning undefined when called req.file
But if I try to see req.body I could see [Object File] in console
PLease suggest where I am going wrong
I think this may help https://github.com/RUSHI-GADHIYA/uploading-and-updating-image see this
Related
I want to upload a file using Multer in a specific directory in my NodeJs app defined by the frontend in vuejs.
It is my first application with multer
The backend code is :
...
const app = express();
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
const storage = multer.diskStorage({
destination: (req, file, cb) => {
//req.body.idUser is undefined here
let destinationPath = path.join("upload_file", req.body.idUser);
if (!fs.existsSync(destinationPath)) {
fs.mkdirSync(destinationPath);
}
cb(null, destinationPath);
},
filename: (req, file, cb) => {
let newFileName = Date.now() + path.extname(file.originalname);
cb(null, newFileName);
},
});
const upload = multer({ storage });
app.post(
"/file/add",
upload.fields([{ name: "newfile" }, { name: "idUser" }]),
(req, res) => {
res.json({
response: "file uploaded",
});
},
);
...
And the frontend code is :
...
async sendDocument(event){
const file = event.target.files[0]
const form = new FormData()
form.append("newfile", file, file.name)
form.append("idUser", this.getIdUser)
const opts =
{
method: "POST",
body: form,
}
const url = "http://localhost:3000/file/add";
try{
await fetch(url, opts)
.then(function (response) {
return response.json();
})
.then(function (res) {
console.log(res)
});
}catch(err){
console.log(err)
}
},
...
I tried to debug step by step with console.log to check why req.body.idUser is not defined in storage and I need it to complete the destinationPath
If I replace req.body.idUser by static value like "toto", all work fine
In front, this.getIdUser is working fine. And req.body.idUser is working in app.post
Thanks for your help
Try appending the ID to the form first:
const form = new FormData()
form.append("idUser", this.getIdUser)
form.append("newfile", file, file.name)
I have a script that allows me to upload files into a folder using React on the frontend and Node on the backend.
I have a folder named client and another named server. When I click on upload file, the file is uploaded.
So what I did is create a new project and moved just the backend, keeping client in the old one. Now, when I click on upload image, I get this error and I don"t know why:
Maybe there is something wrong with Multer?
Code:
server
const path = require("path");
const multer = require("multer");
const storage = multer.diskStorage({
destination: "uploads/",
filename: function (req, file, cb) {
cb(null, "IMAGE-" + Date.now() + path.extname(file.originalname));
},
});
const upload = multer({
storage: storage,
limits: { fileSize: 1000000 },
}).single("file");
exports.filesU = (req, res) => {
upload(req, res, (err) => {
console.log("Request ---", req.body);
console.log("Request file ---", req.file);
//Here you get file.
/*Now do where ever you want to do*/
if (!err) return res.json({ success: true, url: res.req.file.path });
});
};
client
let formdData = new FormData();
const config = {
header: { "content-type": "multipart/form-data" },
};
formdData.append("file", files[0]);
console.log(formdData);
Axios.post(
"http://localhost:4000/api/chat/uploadfiles",
formdData,
config
)
This question already has an answer here:
AngularJS Upload Multiple Files with FormData API
(1 answer)
Closed 3 years ago.
Trying to upload a file from Angularjs UI to nodejs server but facing issues with bodyparser, adding limit to it throws -
"SyntaxError: Unexpected token - in JSON at position 0",
if limit not added throws -
"Payload too large"
I am using connect-multiparty middleware to upload the file. Tried with {limit: '50mb'} in bodyparser and without any limit as well.
UI Code -
$('#imgupload').on('change', function (evt) {
let uploadedFiles = evt.target.files;
let formData = new FormData();
for (var i = 0; i < uploadedFiles.length; i++) {
formData.append("uploads[]", uploadedFiles[i],
uploadedFiles[i].name);
}
let url = "/upload";
httpService.restApi(url,formData)
.then(function (response) {
console.log("the file has been uploaded to local server
",response);
});
});
Nodejs (server code)-
const multipart = require('connect-multiparty');
const multipartMiddleware = multipart({ uploadDir: './uploads' });
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({extended: true}));
app.post('/upload', multipartMiddleware, (req, res) => {
res.json({
'message': 'File uploaded succesfully.'
});
});
Remove the bodyParser middleware from the path:
const multipart = require('connect-multiparty');
const multipartMiddleware = multipart({ uploadDir: './uploads' });
̶a̶p̶p̶.̶u̶s̶e̶(̶b̶o̶d̶y̶P̶a̶r̶s̶e̶r̶.̶j̶s̶o̶n̶(̶{̶l̶i̶m̶i̶t̶:̶ ̶'̶5̶0̶m̶b̶'̶}̶)̶)̶;̶
̶a̶p̶p̶.̶u̶s̶e̶(̶b̶o̶d̶y̶P̶a̶r̶s̶e̶r̶.̶u̶r̶l̶e̶n̶c̶o̶d̶e̶d̶(̶{̶e̶x̶t̶e̶n̶d̶e̶d̶:̶ ̶t̶r̶u̶e̶}̶)̶)̶;̶
app.post('/upload', multipartMiddleware, (req, res) => {
res.json({
'message': 'File uploaded succesfully.'
});
});
The contents is application/form-data, not application/json or application/x-www-form-urlencoded.
If you use multer and make the API call using $http explicitly setting the "Content-Type" header to multipart/form-data you will get "Multer: Boundary not found error" and if you remove the "Content-Type" header or set it to false it throws - "Converting circular structure to JSON error". Hence i used "fetch" to make the API call as it automatically identified the "Content-Type".
UI Code (modified as below) -
$('#imgupload').unbind('change').on('change', function (evt) {
evt.stopPropagation();
evt.preventDefault();
let uploadedFiles = evt.target.files;
let formData = new FormData();
for(let i=0; i<uploadedFiles.length;i++){
formData.append("uploads", uploadedFiles[i], uploadedFiles[i].name);
}
let url = '/upload';
var req = {
method: 'POST',
body: formData
}
fetch(url,req).then(function(response) {
console.log("the file has been uploaded to local server ",response);
$scope.uploadToSftp();
});
});
Nodejs Code (modified as below) -
const multer = require('multer');
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads/')
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
})
const multipartMiddleware = multer({ storage: storage });
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({
extended: true
}));
app.post('/upload', multipartMiddleware.array("uploads",2), function(req, res)
{
console.log("the upload api is called");
return res.send(req.files);
});
So on first server I have route like this:
const express = require('express');
const router = express.Router();
const FormData = require('form-data');
const fetch = require('node-fetch');
const multer = require('multer');
const storage = multer.memoryStorage();
const upload = multer({ storage });
router.post('/', upload.single('file'), async (req, res) => {
const form = new FormData();
form.append('folderId', req.body.folderId);
form.append('file', req.file.buffer, req.file.filename);
const result = await fetch('http://localhost:3003/users', { method: 'POST', body: form }).then(res => res.json());
res.json(result);
})
On this server, it works fine, I can see req.file and it's buffer. So I wanna send this file (without storing it on first server, it exists only in memory and as buffer) to another.
Other server route is like this:
const express = require('express');
const router = express.Router();
const multer = require('multer');
const path = require('path');
const putanja = path.join(__dirname, '../uploads/users');
const storage = multer.diskStorage({
destination: (req, file, cb) => {
console.log('entered here?')
if (!req.body.folderId) return cb({ message: 'no folderId' });
if (!fs.existsSync(putanja + '/' + folderId)) fs.mkdirSync(putanja + '/' + folderId);
cb(null, putanja + '/' + folderId);
},
filename: (req, file, cb) => cb(null, file.originalname)
});
const upload = multer({ storage });
const fs = require('fs');
router.post('/', upload.single('file'), async (req, res) => {
console.log(req.body)
console.log(req.file)
res.json({ status: 'ok' })
})
So on second server, it doesn't even enter the multer middleware, req.file is always defined, and that console.log('entered here?') is never seen. Looks like I'm not passing data as multipart-form?
Also, second server, when sending file directly to it via postman, works.
So my question, how do I send that file? As a buffer? Stream? Base64? I think I tried everything, even changed node-fetch to request, but still no luck.
So on second server, it doesn't even enter the multer middleware, req.file is always defined, and that console.log('entered here?') is never seen. Looks like I'm not passing data as multipart-form?
So this mean your second server doesn't understand the Content-Type of request.
So do one thing add Content-Type parameter in header when you are sending request to second server
Add Content-Type to multipart/form-data
or if you don't know pass headers : {
'Content-Type' : undefined
} http will set header for you
You send your request to /users (http://localhost:3003/users) yet your second server expects the request on /.
Try changing either one to match the other.
'use strict';
const express = require('express');
const multer= require('multer');
const concat = require('concat-stream');
const request = require('request');
const router = express.Router();
function HttpRelay (opts) {}
HttpRelay.prototype._handleFile = function _handleFile (req, file, cb) {
console.log('hell0 proto');
file.stream.pipe(concat({ encoding: 'buffer' }, function (data) {
const r = request.post('/Endpoint you want to upload file', function (err, resp, body) {
if (err) return cb(err);
req.relayresponse=body;
cb(null, {});
});
const form = r.form();
form.append('uploaded_file', data, {
filename: file.originalname,
contentType: file.mimetype
});
}))
};
HttpRelay.prototype._removeFile = function _removeFile (req, file, cb) {
console.log('hello');
cb(null);
};
const relayUpload = multer({ storage: new HttpRelay() }).any();
router.post('/uploadMsgFile', function(req, res) {
relayUpload(req, res, function(err) {
res.send(req.relayresponse);
});
});
module.exports = router;
I am new to node JS and i have made function for uploading image from API.
But when i hit the URL from postman using form-data having field name image then in response it shows me.
Here is the postman image
Error uploading file
below is my code
My router.js contain:-
var express = require('express');
var router = express.Router();
var ctrlSteuern = require('../controllers/steuern.controllers.js');
router
.route('/steuern/image_upload')
.post(ctrlSteuern.imageUpload);
in Controller i have:-
var multer = require('multer');
var multiparty = require('multiparty');
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './image');
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + Date.now());
}
});
var upload = multer({ storage : storage}).single('image');
module.exports.imageUpload = function(req, res){
upload(req,res,function(err) {
if(err) {
return res.end("Error uploading file.");
}
return res.end("File is uploaded");
});
}
Here is my code for saving image to folder.
exports.saveMedia = (req, res) => {
const storage = multer.diskStorage({
destination: (req, file, callback) => {
callback(null, (config.const.path.base + config.const.path.productReviewMedia));
},
filename: (req, file, callback) => {
callback(null, Date.now() + '-' + file.originalname);
}
});
const upload = multer({storage: storage}).any('file');
upload(req, res, (err) => {
if (err) {
return res.status(400).send({
message: helper.getErrorMessage(err)
});
}
let results = req.files.map((file) => {
return {
mediaName: file.filename,
origMediaName: file.originalname,
mediaSource: 'http://' + req.headers.host + config.const.path.productReviewMedia + file.filename
}
});
res.status(200).json(results);
});
}
Here is post man request.