I tried to file upload with NodeJS + ExpressJS + Multer but does not work well.
My ExpressJS Version is 4.12.3
this is my source
server.js:
var express = require('express'),
multer = require('multer');
var app = express();
app.use(express.static(__dirname + '/public'));
app.use(multer({ dest: './uploads/'}));
app.post('/', function(req, res){
console.log(req.body); // form fields
console.log(req.files); // form files
res.status(204).end()
});
app.get('/', function(req, res) {
res.sendFile('public/index.html');
});
app.listen(5000, function() {
console.log("start 5000");
});
public/index.html:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form method="post" enctype="multipart/form-data">
<input id="file" type="file"/>
<button type="submit">test</button>
</form>
</body>
</html>
My NodeJS Console Log when I click Submit Button:
"C:\Program Files\nodejs\node.exe" server.js
start 5000
{}
on NodeJS Console, there is empty object at req.files
Is some problem on my source?
I don't see you calling any API to upload file on click of submit button. Let me give you more comprehensive implementation.
multer config in app.js
app.use(multer({
dest: './uploads/',
rename: function (fieldname, filename) {
return filename.replace(/\W+/g, '-').toLowerCase() + Date.now()
},
onFileUploadStart: function (file) {
console.log(file.fieldname + ' is starting ...')
},
onFileUploadData: function (file, data) {
console.log(data.length + ' of ' + file.fieldname + ' arrived')
},
onFileUploadComplete: function (file) {
console.log(file.fieldname + ' uploaded to ' + file.path)
}
}));
View
<form id="uploadProfilePicForm" enctype="multipart/form-data" action="/user/profile_pic_upload" method="post">
<input type="file" multiple="multiple" id="userPhotoInput" name="userPhoto" accept="image/*" />
<input type="submit" name="submit" value="Upload">
</form>
End point '/user/profile_pic_upload' POST calls uploadProfilePic in controller
var control = require('../controllers/controller');
app.post('/user/profile_pic_upload',control.uploadProfilePic);
Upload profile pic logic in users controller
uploadProfilePic = function(req,res){
// get the temporary location of the file
var tmp_path = req.files.userPhoto.path;
// set where the file should actually exists
var target_path = '/Users/narendra/Documents/Workspaces/NodeExpressWorkspace/MongoExpressUploads/profile_pic/' + req.files.userPhoto.name;
// move the file from the temporary location to the intended location
fs.rename(tmp_path, target_path, function(err) {
if (err) throw err;
// delete the temporary file, so that the explicitly set temporary upload dir does not get filled with unwanted files
fs.unlink(tmp_path, function() {
if (err) {
throw err;
}else{
var profile_pic = req.files.userPhoto.name;
//use profile_pic to do other stuffs like update DB or write rendering logic here.
};
});
});
};
Try this
var multer = require('multer')
var storage = multer.diskStorage({
destination: function (request, file, callback) {
callback(null, './uploads/');
},
filename: function (request, file, callback) {
console.log(file);
callback(null, file.originalname)
}
});
var upload = multer({ storage: storage });
app.post('/', upload.single('photo'), function (req, res) {
console.log(req.body) // form fields
console.log(req.file) // form files
res.status(204).end()
});
ref:
http://wiki.workassis.com/nodejs-express-get-post-multipart-request-handling-example/
Related
I am trying to just do a simple file upload with formidable in node js, and with this code:
`
app.post("/upld", function(req, res){
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
var oldpath = files.filetoupload.filepath;
var newpath = 'uploads/' + files.filetoupload.newFilename;
fs.rename(__dirname + oldpath, __dirname + "/" + newpath, function (err) {
if (err) throw err;
res.write('File uploaded');
res.end();
});
});
});
and here is the html form:
<body>
<form action="upld" method="post" enctype="multipart/form-data">
<input type="file" name="filetoupload"><br>
<input type="submit">
</form>
</body>
</html>
I get an error saying that there is no file or directory named "tmp/9885a1a737766e7a6963b6a00" I know that that temp folder will change everytime, that is just the most recent attempted one.
I have tried looking at the file data by sending it through the response, but all of the information there checks out.
How can I access the uploaded file from its temp folder?
Try this, for the oldpath, do not add the __dirname, just use the oldpath:
const express = require('express');
const formidable = require('formidable');
const fs = require('fs');
const app = express();
app.get('/', (req, res) => {
res.send(`
<form action="upld" method="post" enctype="multipart/form-data">
<input type="file" name="filetoupload"><br>
<input type="submit">
</form>
`);
});
app.post("/upld", function (req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
var oldpath = files.filetoupload.filepath;
var newpath = 'uploads/' + files.filetoupload.newFilename;
fs.rename(oldpath, __dirname + "/" + newpath, function (err) { // <<======= ONLY oldpath DO NOT ADD __dir
if (err) throw err;
res.write('File uploaded');
res.end();
});
});
});
app.listen(3000, () => {
console.log('Server listening on http://localhost:3000 ...');
});
I am able to store image path in mongodb.Here I am storing image paths in array format. Using document Id I need to add another image i.e., I want to push another image path into that array.So my question is how can I store another image path in mongodb.
Here I am uploading image using html file. This is my code index.html
<form id="uploadForm"
enctype="multipart/form-data"
action="/api/file"
method="post"
>
<input type="file" name="userFile"/>
<input type="submit" value="Upload File" name="submit">
</form>
Here is my server code server.js
var express=require('express');
var multer=require('multer');
var bodyParser = require('body-parser');
var Image=require('./models/image');
var Product=require('./models/product');
var mongoose=require('mongoose');
var path = require('path');
var rand;
var urlencodedParser = bodyParser.urlencoded({ extended: false });
var config = require('./config');
mongoose.connect(config.mongoUrl);
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () {
console.log("Connected correctly to server");
});
var app=express();
var ejs = require('ejs')
app.set('view engine', 'ejs')
var storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, './public/uploads')
},
filename: function(req, file, callback) {
//callback(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
//callback(null, file.originalname)
rand=Date.now() + path.extname(file.originalname);
callback(null, file.fieldname + '-' + rand);
}
})
var upload = multer({
storage: storage});
app.get('/api/file',function(req,res){
res.sendFile('E:/saas/nodejs/uploads/db/views/index.html');
});
app.post('/api/file',upload.single('userFile'), function(req, res) {
console.log(req.file);
console.log(req.file.path);
Image.create({imagePaths:[{imagepath:req.file.path}]},function(err,img){
if (err) throw err;
console.log(img);
console.log('Path created!');
var id = img._id;
res.writeHead(200, {
'Content-Type': 'text/plain'
});
res.end('Added the image path with id: ' + id);
});
})
var route=require('./routes/route');
app.use('/route',route);
app.listen(3000,function(){
console.log("Server listening on 3000");
});
After running the server I will use this in browser http://localhost:3000/api/file using this I am able to upload file and I will get mongodb document id in response.Using this Id how can I upload another image path.
Use $push to store path in array
schemaName.findByIdAndUpdate(
{ req.headers.id },
{ $push: { imagePath: '/newPath' } },
(err,response)=>{
if(err){
console.log(err);
}
});
I get the same error with this question: What type of error is this Error: ENOENT: no such file or directory, open
However, I get the same error for all type of folder I choose and I'm sure that I choose only one file. I gives this error
Error: ENOENT: no such file or directory, open 'uploads/userPhoto-1501659100410'
Also, to be clear, my code:
Server.js
var express = require("express");
var multer = require('multer');
var app = express();
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './uploads');
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + Date.now());
}
});
var upload = multer({ storage : storage}).single('userPhoto');
app.get('/',function(req,res){
res.sendFile(__dirname + "/index.html");
});
app.post('/api/photo',function(req,res){
upload(req,res,function(err) {
if(err) {
return res.end(err+" ");
}
res.end("File is uploaded");
});
});
app.listen(3000,function(){
console.log("Working on port 3000");
});
index.html
<form id = "uploadForm"
enctype = "multipart/form-data"
action = "/api/photo"
method = "post"
>
<input type="file" name="userPhoto" />
<input type="submit" value="Upload Image" name="submit">
</form>
Also I wonder if I can put the text inside the .js file into script and put both of them in the same jsp file. Because when I do that, I cannot get any output from that and I change the port of tomcat that I use as server in eclipse but it says
The requested resource is not available.
I'm trying to upload a photo using Node.js. But when I upload, it shows this error:
Cannnot read property file of undefined
at C:\new\file.js:13:26
Looks like I'm doing something wrong with req.files.file.name which I don't understand. What can be the issue?
Here's the code:
file.js
var express = require('express');
var app = express();
var fs = require('fs');
var bodyParser = require('body-parser');
var multer = require('multer');
app.use(express.static('public'));
app.use(bodyParser.urlencoded({extended: false}));
app.use(multer({dest: '/files/'}).single('file'));
app.get('/index.html', function (req, res) {
res.sendFile(__dirname + '/' + '/index.html')
});
app.post('/file_upload', function (req, res) {
console.log(req.files.file.name);
console.log(req.files.file.path);
console.log(req.files.file.type);
var file = __dirname + '/' + req.files.file.name;
fs.readFile(req.files.file.name, function (err, data) {
fs.writeFile(file, data, function (err) {
if (err) {
console.log("Error reading");
} else {
response = {
message: 'file uploaded successfully',
filename: req.files.file.name
};
}
console.log(response);
res.end(JSON.stringify(response));
});
});
});
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("The server is running at http://%s:%s ", host, port);
});
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:8081/file_upload" method="POST" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="submit">
</form>
</form>
</body>
</html>
Here's what I do, which works fine:
var uploadPath = 'public/uploads/';
var upload = multer({dest: uploadPath});
router.post('/image', upload.single('thePhoto'), function (req, res) {
var uploadedFile = uploadPath + req.file.filename;
The problem can be caused because you have already added multer in app.use() which parses all the data before the control goes to post method. So I think you should either use fs or multer but not both.
I am trying a simple node.js file upload code for test purpose by using express and multer modules.My code look for html like :-
<html>
<head>
<title>File Uploading Form</title>
</head>
<body>
<h3>File Upload:</h3>
Select a file to upload: <br />
<form action="http://127.0.0.1:8081/file_upload" method="POST"
enctype="multipart/form-data">
<input type="file" name="file" size="50" />
<br />
<input type="submit" value="Upload File" />
</form>
</body>
and my server.js code look like :-
var express = require('express');
var app = express();
var fs = require("fs");
var bodyParser = require('body-parser');
var multer = require('multer');
app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(multer({ dest: '/tmp/'}));
app.get('/index.html', function (req, res) {
res.sendFile( __dirname + "/" + "index.html" );
});
app.post('/file_upload', function (req, res) {
console.log(req.files.file.name);
console.log(req.files.file.path);
console.log(req.files.file.type);
var file = __dirname + "/" + req.files.file.name;
fs.readFile( req.files.file.path, function (err, data) {
fs.writeFile(file, data, function (err) {
if( err ){
console.log( err );
}else{
response = {
message:'File uploaded successfully',
filename:req.files.file.name
};
}
console.log( response );
res.end( JSON.stringify( response ) );
});
});
});
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)
});
Now while I run the server.js from command prompt like :- node server.js My server doesn't get started and it throws some error like image :-
SOuřaan Gřg,
Your line, var multer = require('multer'); is returning and object, not the middleware function. There are three middleware functions you can use.
Check out the docs.
In case you need to handle a text-only multipart form, you can use any of the multer methods (.single(), .array(), fields()).
.single(fieldname) Accept a single file with the name fieldname. The single file will be stored in req.file.
.array(fieldname[, maxCount]) Accept an array of files, all with the
name fieldname. Optionally error out if more than maxCount files are
uploaded. The array of files will be stored in req.files.
.fields(fields) Accept a mix of files, specified by fields. An object
with arrays of files will be stored in req.files.
You must change app.use(multer({ dest: '/tmp/'}));. You are passing an object.
Also according to the docs:
WARNING: Make sure that you always handle the files that a user uploads. Never add multer as a global middleware since a malicious user could upload files to a route that you didn't anticipate. Only use this function on routes where you are handling the uploaded files.
You should be assigning the middleware to route in where you are handling the upload. For your case you could do the following:
var upload = multer({ dest: '/tmp/' });
app.post('/file_upload', upload.single('file'), function (req, res, next) {
// req.file is the `file` file
// req.body will hold the text fields, if there were any
})