i'm using multer to get a file from this form
<form action="/api/pimage" method="POST" enctype="multipart/form-data">
<fieldset>
<input type="file" name="profileimage">
<input type="submit">
</fieldset>
</form>
using this serverside script
app.post('/api/pimage', function(req, res, next) {
console.log(req.body, req.files);
});
the problem is that req.body is printing out { profileimage: 'image.png' }
and req.files is printing out {}
where you see the problem?
thanks
P.S. i'm using app.use(bodyParser.urlencoded({ extended: false })); to get req.body and app.use(multer({ dest: './uploads/'})); for req.files
I found that using multer alongside bodyParser can cause req.file to be undefined. Make sure to check that also if you're having issues.
I put MY (there are many I imagine and surely better) solution to help many people like me because I have searched during 1 entire day ;-(
var express = require('express');
var fileUpload = require('express-fileupload');
var fs = require("fs");
var app = express();
console.log('étape 0');
app.use(express.static('mesStatic'));
app.use(fileUpload());
console.log('étape 1');
app.get('/indexFileUpload.htm', function (req, res) {
res.sendFile( __dirname + "/" + "indexFileUpload.htm" );
})
console.log('étape 2');
app.post('/file_upload', function (req, res) {
console.log('étape 3');
console.log('req.files:' , req.files);
if (!req.files) {
res.send('No files to upload.');
return;
}
console.log('req.files.file.data:' , req.files.file.data);
var bufDataFile = new Buffer(req.files.file.data, "utf-8");
console.log('étape 3.1');
console.log('__dirname : ' + __dirname);
fs.writeFile(__dirname + '/file_upload/output.txt', bufDataFile, function(err) {
if (err) {
return console.error(err);
}
else {
console.log("Data written successfully !");
}
console.log('étape 4');
res.end('Fin OK !!!');
})
})
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port);
})
You have to provide your upload function defined for multer before asking for req.file in function(req, res), you can follow the code given below
var Storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, "./images/");
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '_' + Date.now() + '.jpg');
}
});
var upload = multer({ storage: Storage }).single('imagePath');
router.post('/file_upload', upload, function(req, res, next){
console.log(req.file);
var Storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, "./public/images/");
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '_' + Date.now() + '.jpg');
}
});
var upload = multer({ storage: Storage }).single('imagePath');
router.post('/add-product', upload, function(req, res, next){
var newProduct = new Product();
}
Related
I the app.js there is a direct route app.post('/upload', upload.single('image'), (req, res) => { res.json({ message: 'pic uploaded' }); });
When I make a post request to /upload, the image will be uploaded. However, when I use it like app.use('/phones', phoneRoutes); then the image won't be uploaded. Can you tell me where is the mistake? In both files everything is the same, but as I said, it works only in the app.js.
app.js:
require('dotenv').config();
const express = require('express');
const mongoose = require('mongoose');
const phoneRoutes = require('./routes/phoneRoute');
const multer = require('multer');
const cors = require('cors');
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, './images');
},
filename: (req, file, cb) => {
console.log('file: ', file);
cb(null, Date.now() + file.originalname);
},
});
const upload = multer({ storage: storage });
//initialize
const app = express();
//middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());
//routes
app.post('/upload', upload.single('image'), (req, res) => {
res.json({ message: 'pic uploaded' });
});
app.use('/phones', phoneRoutes);
//connect to mongodb
mongoose
.connect(process.env.MONGO_URI)
.then(() => {
app.listen(process.env.PORT);
console.log('Connected to mongodb: ', process.env.PORT);
})
.catch((err) => console.log(err));
phoneRoutes.js:
const router = require('express').Router();
const { createPhone } = require('../controllers/phoneController');
const multer = require('multer');
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, '../images');
},
filename: (req, file, cb) => {
console.log('file: ', file);
cb(null, Date.now() + file.originalname);
},
});
const upload = multer({ storage: storage });
router.get('/:id', (req, res) => {
res.json({ message: 'get phone: ' + req.params.id });
});
router.get('/', (req, res) => {
res.json({ message: ' all Phones' });
});
router.delete('/:id', (req, res) => {
res.json({ message: 'phone ' + req.params.id + ' is deleted' });
});
router.post('/', upload.single('image'), (req, res) => {
res.json({ message: 'pic is uploaded' });
});
module.exports = router;
Your statement
cb(null, '../images');
contains a relative path, which is probably evaluated relative to the current working directory of the Node.js process. It is safer to make it relative to the directory containing the Javascript file phoneRoutes.js:
cb(null, __dirname + '/../images');
Controller.js
var multer = require('multer');
var upload = (req, res) => {
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads/');
},
filename: function (req, file, cb) {
var dateTimestamp = Date.now();
cb(null, file.originalname.split('.')[file.originalname.split('.').length - 2] + '-' + dateTimestamp + '.' + file.originalname.split('.')[file.originalname.split('.').length - 1]);
}
});
var upload = multer({
storage: storage
}).single('file');
upload(req, res, function (err) {
console.log(req.file);
if(err) {
res.json({ error_code: 1, err_desc: err });
return;
}
res.json("File uploaded sucessfully");
});
};
module.exports ={
upload:upload
}
app.js
var mongoose = require("mongoose");
var multipart = require('connect-multiparty');
app.use(cors({origin:true, credentials:true}));
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({limit: '50mb',extended: true}));
app.use(multipart({}));
mongoose.Promise = global.Promise;
mongoose.connect("mongodb://127.0.0.1:27017/mydb");
var UploadRouter =require('./upload/uploadRouter/upload-doc-router');
app.use('/upload', UploadRouter);
var PORT = process.env.PORT || 4000;
app.listen(PORT, function(){
console.log('Running on Port 4000...');
});
router:
var express =require("express");
var URouter = express.Router();
var Upload = require('../uploadControllers/upload-doc-controllers');
URouter.route('/single/file').post(Upload.upload);
module.exports =URouter;
Above are the my code.I want to upload pdf,word document and store in one folder.when i test the api getting syntax error Unexpected token - in JSON at position 0 , JSON.parse (<anonymous>), createStrictSyntaxError like that shows error in postman .when i choose file in pdf then send the request to the api.
I removed headers and in body section i select form-data
It simply doesn't save anything to the destination folder i specified.
i tried {storage:storage} instead of {dest: 'storage/'} but it didn't work either.
the image data is actually sent to the server as its console logged. and the dest i specified is created by default but remain empty.
const express = require('express');
const app = express();
const multer = require('multer');
let storage = multer.diskStorage({
destination: '/public/my-uploads',
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
});
const upload = multer({dest:'storage/'}).single('file');
app.post('/upload', upload, (req , res) => {
console.log(req.files) // this does log the uploaded image data.
})
***** EDIT ******
HTML
<form onSubmit={this.upload} enctype='multipart/form-data'>
<input type='file' name='image' />
<input type='submit' value='upload' />
</form>
JS
upload(e){
e.preventDefault();
const file = e.target[0].files[0];
console.log(file)
const fm = new FormData();
fm.append('file', file);
console.log(fm)
axios.post('/upload', fm);
}
POSTMAN
Try to catch the error my calling the middleware yourself:
var upload = multer().single('avatar')
app.post('/upload', function (req, res) {
upload(req, res, function (err) {
if (err) {
// An error occurred when uploading
return
}
// Everything went fine
})
})
Also, change the storage to this:
let storage = multer.diskStorage({
destination: function(req, file, ca) {
cb(null, '/public/my-uploads');
}
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
});
It's been a while, the issue was that I wasn't using the multer middleware at all so the callback code for handling the image was never executed.
I didn't know much about how express worked back then.
Seems you are not using the storage variable and use a function for the destination key, as written in the documentation, also you need to pass your file in the input field named field otherwise multer can't store the file, create an storage folder on the same level as the code :
const http = require('http')
const port = 3000
const express = require('express');
const app = express();
const multer = require('multer');
const server = http.createServer(app)
let storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './storage')
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
});
const upload = multer({ storage }).single('file');
app.post('/upload', upload, (req, res) => {
console.log(req.files) // this does log the uploaded image data.
})
// bind the server on port
server.listen(port, (err) => {
if (err) {
return console.log('something bad happened', err)
}
console.log(`server is listening on ${port}`)
})
The name of the "single" in ...single('file') must match the name in the input (containing the file) <input type="file" name='image' /> - and it does not in your example.
Change the multer-part to this ...single('image') - as in the input name='image'
Try this File Storage For Save image in Local
const fileStorage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "images");
},
filename: (req, file, cb) => {
cb(
null,
new Date().toISOString().replace(/:/g, "-") + "-" + file.originalname
);
},
});
I have a problem with my uploader. I think everything with code is right and still the file isnt created in uploads folder. Also when i try to console.log(req.files) i get an empty array. I try to make it locally
Here is the code:
const express = require("express"),
app = express(),
multer = require("multer"),
bodyParser=require("body-parser"),
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './uploads/');
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + Date.now() + '.' + mime.extension(file.mimetype));
}
});
var upload = multer({ storage : storage }).array('userPic');
app.post("/postFormAct", isLoggedIn, function(req, res){
upload(req,res,function(err) {
console.log(req.files);
});
});
Also there is my form:
<form method="post" action="/postFormAct" enctype="multipart/form-data">
<input type="text" name="user"><br>
<input type="text" name="email"><br>
<input type="file" name="userPic"><br>
<input type="submit" value="Submit">
</form>
I think you have an issue with your function level middleware, you have isLoggedIn, you have to chain the multer middleware upload right after like so :
// ...
var upload = multer({ storage : storage }).array('userPic');
app.post("/postFormAct", isLoggedIn, upload, function(req, res){
console.log(req.files)
});
Here's a full working example :
const app = require('express')()
const bodyParser = require('body-parser')
const multer = require('multer')
const morgan = require('morgan')
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads')
},
filename: (req, file, cb) => {
cb(null, file.fieldname + '-' + Date.now())
}
})
const upload = multer({
storage: storage
})
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.use(morgan('dev'))
isLoggedIn = (req, res, next) => {
console.log('check if user is logged in')
next()
}
app.post('/uploads', isLoggedIn, upload.array('images'), (req, res) => {
console.log(req.files);
return res.send(req.files);
})
app.listen(8000, () => {
console.log(`server is listenning on port 8000`)
})
You can find a test repository here
Also make sure that your destination dir exist.
Instead of var upload = multer({ storage : storage }).array('userPic');
use
var upload = multer({ storage : storage }).any('userPic');
.any()
Accepts all files that comes over the wire. An array of files will be stored in req.files.
I just discovered something about Express middleware with multer.
You need to pass an array as middleware if you have more than one function that needs to act as middleware.
So this:
app.post('/uploads', isLoggedIn, upload.array('images'), (req, res) => {
console.log(req.files);
return res.send(req.files);
})
should become this:
app.post('/uploads', [upload.array('images'), isLoggedIn], (req, res) => {
console.log(req.files);
return res.send(req.files);
})
Note: Also notice that the upload middleware needs to go first...I don't know why this happens but that's the only way it worked for me.
I'm just putting this out there if anyone needs help with this(even though the question is pretty old and has an accepted answer).
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.