I'm trying to create HTML form for uploading image to server with Node.js. I tried to do it with Formidable and Multer. In Formidable I got my Fields object normally but files object was undefined. In Multer I get my req.body normally but req.file is undefined.
I tried to do same with Formidable and no express and everything worked fine, but same didn't worked with express
here is my backend
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(publicPath));
const upload = multer({ storage: multer.memoryStorage() });
app.post('/fileupload', upload.single('testFile'), (req, res, next) => {
const file = req.file;
if (!file) {
const error = new Error('Please upload a file');
error.httpStatusCode = 400;
return next(error);
}
res.send(file);
});
and my frontend
<form class="upload__form" action="/fileupload" method="POST" enctype="multipart/form-data" >
<input type="file" name="testFile" id="file" accept="image/*">
<label for="file" class="hover">Choose a file <i class="fas fa-upload"></i> </label>
<span id="err_msg"></span>
<div class="tag-input">
<input placeholder="Type tags..." class="input" type="text" name="query"><button class="search" type="submit"><b>Add <i class="fas fa-arrow-right"></i></b></button>
<p class="note">*Seperate with commas <i class="far fa-times-circle hover note-close" ></i></p>
</div>
</form>
The code above is with multer, but I also tried with Formidale, nothing changed
I tried your code and it works perfectly, what you could try is not to use a middleware instead of using a function to know if your code is returning an exception.
const upload = multer({ storage: multer.memoryStorage() }).single('testFile');
app.post('/fileupload', (req, res, next) => {
upload(req, res, function (err) {
if (err || !req.file) {
// An error occurred while loading the image.
const error = new Error('Please upload a file')
error.httpStatusCode = 400;
return next(error);
}
res.send(req.file);
});
});
This way you could check if req.file is undefined or if it brings an error in the variable err.
Related
I am getting an error in my application when I want to upload an image with Multer. I already tried to change the name and the loading address but still did not achieve anything. Any ideas ?
This is the code:
const multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, cb){
cb(null, path.join(__dirname,'../views/upload'));
},
filename: function(req, file, cb){
cb(null, file.fieldname + Date.now());
}
})
var upload = multer({
storage: storage
})
Route:
router.post('/user/change/image', upload.single('image'), isAuthenticated, (req, res) =>{
const file = req.file.image
if(!file) {
req.flash('error', 'Porfavor introduce un archivo valido')
} else {
res.send(file)
res.redirect('/user')
}
})
Form EJS:
<div class="tarjetaedit col-sm-6">
<form method="POST" action="/user/change/image" role="form" enctype="multipart/form-data">
<div class="form-group">
<legend class="legend">Imágen de perfil</legend>
<input type="file" class="form-control" name="image" accept="image/*">
</div>
<div class="form-group">
<button type="submit" class="btn btn-success btn-block">Subir foto</button>
</div>
</form>
</div>
Thanks to all ! I really need to fix this <3
I am using Multer to save files I upload through a form but I do not know why my code saves it as a weird name and without extension and I have just used the code from the documentation.
server.js:
const multer = require('multer');
const app = express();
var upload = multer({ dest: 'uploads/' })
app.post('/file', upload.single('filesToAttach'), function (req, res, next) {
console.log(req.file);
loadUserPage(req, res);
})
userPage.ejs:
<form action="/file" method="post" enctype="multipart/form-data">
<div id="frm-attachments">
<div>
<h3>Attachments</h3>
<div>
<input type="file" id="attachFiles" name="filesToAttach" />
<input type="submit" value="Attach">
</div>
<div id="frm-attach-files">
Attached files
<div>
<textarea id="field-attached-files" class="large-textbox" name="attached-files" spellcheck="true" rows="10" cols="50" tabindex="4" disabled="true"></textarea>
</div>
</div>
</div>
</div>
</form>
When I click on the submit button, a new file appear in the folder uploads which is supposed to have the same name and same extension as the file I uploaded in the form, but it has this name instead:
And if I try to print out(req.file), I see this:
Why is this happening? I do not even understand why they write the wrong code in the documentation...
You can set it externally,
Try this,
const multer = require('multer');
const app = express();
var storage = multer.diskStorage({
destination: 'uploads/',
filename: function(req, file, callback) {
callback(null, file.originalname);
}
});
var upload = multer({ storage: storage })
app.post('/file', upload.single('filesToAttach'), function (req, res, next) {
console.log(req.file);
loadUserPage(req, res);
})
You should make a unique name to save your file "generate a random string" and concat this this with the mimetype of your file. as you can see mimetype is already present in the req.file ,
function getFileExtension(mimeType){
if ( mimeType=== 'image/png') {
return '.png';
}
else if ( mimeType=== 'image/jpg') {
return '.jpg';
}
else if ( mimeType=== 'image/gif') {
return '.gif';
}
else {
return '.jpeg';
}
}
If you ae working on images this is the a utility function pass req.mimetype to this and concat its return value to your generated name
I have a file upload in node js. I want to show a line displaying upload started / upload failed / upload completed and a graphic progress bar.
How can I implement this?
Node.js:
var express = require('express');
var router = express.Router();
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './upload');
},
filename: function (req, file, cb) {
cb(null, file.originalname + '-' + Date.now());
}
});
var upload = multer({ storage : storage}).array('file', 3);
router.get('/', function(req, res){
res.send( {success: 'File uploaded!'});
})
router.post('/upload', function(req,res){
upload(req,res,function(err) {
console.log('Selected Files: ', req.files);
if(err){
res.end("Error: '" , err , "'");
}else{
console.log('Files uploaded!');
res.sendStatus(204);
}
});
});
module.exports = router;
HTML
<form enctype = "multipart/form-data"
action = "/upload"
method = "POST"
>
<input type="file" name="file"/>
<p></p>
<input type="file" name="file"/>
<p></p>
<input type="submit" value="Upload File" name="submit">
</form>
<p id="success">{{success}}</p>
Use XMLHttpRequest and .addEventListener("progress") on the client side to submit the form
HTML code:-
<html>
<body>
<form action="http://localhost:3000/api" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit">
</form>
</body>
</html>
The code in nodeJS is
app.post('/api',function (req, res) {
//JSON.stringify(req.files);
console.log(JSON.stringify(req.files));
var file = req.files.file;
var stream = fs.createReadStream(file.path);
});
I want to print the details of the-files.
I am getting error
TypeError: Cannot read property 'file' of undefined
at /Users/mAddy/Desktop/check1/server.js:27:25
Use multer, as express/connect no longer supports multipart on its own. Also, use the post method on the express/connect app.
After installing multer:
var multer = require('multer');
var upload = multer({dest:'uploads/'});
app.post('/api', upload.single('file'), function (req, res) {
res.sendStatus(200);
});
<form action="http://localhost:3000/examples" method="post" enctype="multipart/form-data" accept="application/json">
<input type="text" name ="name">
<input type="text" name ="codedescription">
<input type="file" name ="file">
<input type="submit" value="Upload selected file to server">
</form>
var multer = require('multer');
app.use(multer({ dest: './uploads/',
onFileUploadStart : function(file){
console.log('File recieved:');
console.log(file);
},
onFileUploadData:function (file,data){
console.log('Data recieved');
},
onParseEnd: function(req,next){
next();
}
}));
app.route('/examples').post(users.requiresLogin, examples.create);
exports.create = function(req, res) {
console.log("req.files"+req.files);
console.log("req.name"+req.body.name);
console.log("req.codedescription"+req.body.codedescription);
};
Submit form without enctype="multipart/form-data" is working but I can not get files.
Submit form with enctype="multipart/form-data" is working but I can not get files as well as data.
you can try this
<html>
<head>
<title>FileUpload</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
</head>
<body>
<form id = "uploadForm"
enctype = "multipart/form-data"
action = "http://localhost:3000/api/photo"
method = "post"
>
<input type="file" name="userPhoto" multiple />
<input type="submit" value="Upload Image" name="submit" id="btnUpload">
<span id="spnStatus" />
</form>
<script>
$(document).ready(function(){
$('#btnUpload').click(function(){
$('#spnStatus').empty().text("File is Uploading");
$(this).ajaxSubmit({
error : function(xhr){
status('Error : '+xhr.status);
}
success : function(response){
$('#spnStatus').empty().text(xhr);
}
});
});
});
</script>
</body>
</html>
NodeJS Express
var express = require("../node_modules/express");
var multer = require('../node_modules/multer');
var bodyParser = require("../node_modules/body-parser");
var app = express();
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());
}
});
var upload = multer({ storage : storage }).array('userPhoto',8);
app.get('/',function(req,res){
res.sendFile(__dirname + "/fileUpload.html");
});
app.post('/api/photo',function(req,res){
upload(req,res,function(err) {
if(err) {
console.log(err);
return res.end("Error uploading file.");
}
res.end("File is uploaded");
});
});
app.listen(3001,function(){
console.log("Working on port 3001");
});
Now you can upload upto 8 files at a time, if you want to upload more than eight, just edit var upload = multer({ storage : storage }).array('userPhoto','LIMITHERE');
#karthik comment, i think you need this as well including after jquery, when you want to use his example:
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery.form/3.51/jquery.form.min.js"></script>