I'm attempting to upload a file with express-fileupload (express-fileupload) in Node js.
But I wasn't successfully yet.
My app.js (where my express server is running) looks like this:
const express = require('express');
const exphbs = require('express-handlebars');
const fileUpload = require('express-fileupload');
const app = express();
const port = 5000;
app.use(fileUpload({
debug: true
}));
app.use(express.static('./upload'));
const routes = require('./server/routes/task');
app.use('/', routes);
app.listen(port, () => console.log(`Listening on port ${port}`));
My task.js (where my routes are) looks like this:
const express = require('express');
const router = express.Router();
const taskController = require('../controllers/taskController');
router.post('/admin/fileUpload', taskController.fileUpload);
module.exports = router;
My taskController.js (where my routes are getting controlled) looks like this:
exports.fileUpload = (req, res) => {
let sampleFile;
let uploadPath;
if (!req.files || Object.keys(req.files).length === 0) {
res.render('admin', { error: `No files were uploaded!` });
} else {
sampleFile = req.files.sampleFile;
uploadPath = __dirname + '/upload/' + sampleFile.name;
sampleFile.mv(uploadPath, function (err) {
if (err) throw err;
res.render('admin', { alert: `File ${sampleFile.name} successfully uploaded!` });
}
}
}
My admin.hbs (I'm also using express-handlebars) looks like this:
<form method="POST" action="/admin/fileUpload">
<h2>Upload File</h2>
<input type="file" enctype="multipart/form-data" name="sampleFile">
<button type="submit">
</form>
So, my log looks like this when I start the express server:
[nodemon] starting `node app.js`
Listening on port 5000
Express-file-upload: Request is not eligible for file upload!
I'm trying to find the issue for hours but haven't had any luck yet.
So, it took me a while but I found my issue.
I've made a two little mistakes in my form and in my upload path.
<form method="POST" action="/admin/fileUpload">
<h2>Upload File</h2>
<input type="file" enctype="multipart/form-data" name="sampleFile">
<button type="submit">
</form>
Thats wrong. I've added the "enctype" in the wrong place. It should be in the form and not in the input field.
Solution for my form:
<form method="POST" action="/admin/fileUpload" enctype="multipart/form-data">
<h2>Upload File</h2>
<input type="file" name="sampleFile">
<button type="submit">
</form>
Solution for my upload path:
Instead of
uploadPath = __dirname + '/upload/' + sampleFile.name;
I need to do this
uploadPath = './upload/' + sampleFile.name;
Related
The following lines of code deliver the localhost/join page.
routes.js file
module.exports = function (app){
app.get("/join", function (req, res){
res.render("join");
});
};
app.js file
var express = require("express");
var app = express();
require('./routes')(app);
app.listen(3000, function(){
console.log("Server started at localhost:3000. Ctrl+C to exit.");
});
join.ejs file
<h1> You can sign up here </h1>
<input type="email" placeholder="email address"> </input>
<br>
<input type="password" placeholder="password"> </input>
<br>
<input type="submit"> </input>
Yet when I try to create an app.post() route (which works when in the app.js file) it gives me the error
app not defined
Why would this be given for app.post() and not app.get()? Why is require('/routes')(app); not equivalent to having the same code in one app.js file?
Your app.js should look like follows:
var express = require('express')
var app = express()
require('./routes')(app);
app.listen(PORT-NUMBER)
If yes then it will helpful to know how your routes.js looks like with app.post() route.
I am trying to use mutler in a simple exercise of learning nodejs. After I upload the file, get the "Unexpected filed" error. I tried everything it was written on this subject but I still cannot get rid of this error.
Here is my node.js code:
var express = require('express');
var app = express();
var fs = require("fs");
var bodyParser = require('body-parser');
var multer = require('multer');
var upload = multer({dest: 'tmp/'});
var type = upload.single('avatar');
app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: false }));
app.get('/', function (req, res) {
res.sendFile( __dirname + "/" + "upload.html" );
})
app.post('/file_upload', type, async (req, res) => {
console.log(req.file);
})
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)
})
The html file used for upload:
<html>
<head>
<title>File Uploading Form</title>
</head>
<body>
<h3>Upload Profile:</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>
</html>
And the error I get in the web browser after upload:
Error: Unexpected field
at makeError (/home/mihai/nodejs/tutorial/node_modules/multer/lib/make-error.js:12:13)
at wrappedFileFilter (/home/mihai/nodejs/tutorial/node_modules/multer/index.js:40:19)
at Busboy.<anonymous> (/home/mihai/nodejs/tutorial/node_modules/multer/lib/make-middleware.js:114:7)
at emitMany (events.js:146:13)
at Busboy.emit (events.js:223:7)
at Busboy.emit (/home/mihai/nodejs/tutorial/node_modules/busboy/lib/main.js:38:33)
at PartStream.<anonymous> (/home/mihai/nodejs/tutorial/node_modules/busboy/lib/types/multipart.js:213:13)
at emitOne (events.js:115:13)
at PartStream.emit (events.js:210:7)
at HeaderParser.<anonymous> (/home/mihai/nodejs/tutorial/node_modules/dicer/lib/Dicer.js:51:16)
Can anybody tell me how to make it work? I have tried also on a Windows 7, with node v8.8.1 and get the same error.
The error indicates that multer encountered a file field in the request that it wasn't expecting.
You've told multer to expect a single field called avatar:
var type = upload.single('avatar');
Your file field is actually called file:
<input type="file" name="file" size="50" />
Change it to avatar and everything should work fine:
<input type="file" name="avatar" size="50" />
Basically I want to upload a csv file from local computer and parse it in the backend to do required operations. I'm attaching the csv file in the front end. Checked that its not empty. But I'm unable to fetch the same in the server.
Is there something I'm missing or doing in the wrong way?
Here is what I have tried till now.
Front end code:
<form id="myForm" method="POST" enctype="multipart/form-data" action='/testcsv' >
<input type="file" id="file" />
<input type="submit" value="Submit">
</form>
Backend Code:
var express = require('express');
var methodOverride = require('method-override');
var http = require('follow-redirects').http;
var formidable = require('formidable');
var app = express();
const fs = require('fs');
app.use(methodOverride('_method'));
var bodyParser = require('body-parser');
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
app.post('/testcsv', requireLogin, function(req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
console.log(err);
console.log(fields);
console.log(files);
});
});
Log Output:
null
{}
{}
This problem is caused by Frontend code, it has nothing to do with Backend code (formidable).
For the following console.log statement:
console.log(err);
console.log(fields);
console.log(files);
err is null because there is no error.
fields is {} because in the form, all input fields are file selector. fields in formidable only indicate plain input field, such as <input type="text">.
files is {} because the name of file selector in the form is missing.
To get expected value, here is an example form:
<form id="myForm" method="POST" enctype="multipart/form-data" action='/testcsv' >
<input type="text" name="testtext" />
<input type="file" id="file" name="testfile" />
<input type="submit" value="Submit">
</form>
The console.log result for above form would be:
null
{ testtext: '....' }
{ testfile: File....}
I am trying to upload a file with express-fileupload and am having no luck getting it to work. I can get the file (in this case an image) to 'upload' in the sense that I can get the console to show an image uploaded with the correct folder.
startup.js
router.get('/upload', function(req, res) {
res.render('upload');
});
router.post('/upload', function(req, res) {
// The name of the input field (i.e. "sampleFile") is used to retrieve the uploaded file
let startup_image = req.files.image;
// Use the mv() method to place the file somewhere on your server
startup_image.mv('/images' , function(err) {
if (err) {
console.log(err);
}
});
});
Then my html form is
<form ref='uploadForm'
id='uploadForm'
action='/upload'
method='post'
encType="multipart/form-data">
<input type="file" name="image" />
<input type='submit' value='Upload!' />
</form>
You are pointing the directory where the file would go to, but you are not giving it a file name. I would say let the user decide the file name for the client side and add it to the path.
<input name="userFileName" type="text">//userFilename Here</input>
var myFILENAME = req.body.userFilename
startup_image.mv('/images/'+myFILENAME+'.jpg', ..) //myFILENAME needs to be added here
Also please see Full Example in how to upload files with express-fileupload
UPDATE
I found solution to your problem you need to add __dirname to this line which will let the program know your current directory to your source code.
startup_image.mv(__dirname + '/images' , function(err) {..
UPDATE 2
Here is my source code, if you want you can try it with this.
my html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form ref='uploadForm' encType="multipart/form-data" class="" action="/upload" method="post">
<input type="text" name="fileName" value=""><br>
<input type="file" name="foo" value=""><br>
<input type="submit" name="" value="upload!">
</form>
</body>
</html>
my main source
var express = require("express);
var app = express();
const fileUpload = require('express-fileupload');
//npm install ejs, express, express-fileupload
//middleware
app.use(express.static(__dirname));
app.set('view engine', 'ejs');
app.use(fileUpload());
app.get('/inputFile', function(req, res){
res.render('inputt');
});
app.post('/upload', function(req, res) {
// The name of the input field (i.e. "sampleFile") is used to retrieve the uploaded file
var startup_image = req.files.foo;
var fileName = req.body.fileName;
// Use the mv() method to place the file somewhere on your server
startup_image.mv(__dirname + '/images/' + fileName + '.jpg' , function(err) {
if(err){
console.log(err);
}else{
console.log("uploaded");
}
});
});
app.listen(7777);
using async/await style
in your server file do this
const fileUpload = require('express-fileupload');
app.use(
fileUpload({
limits: { fileSize: 50 * 1024 * 1024 },
useTempFiles: true,
// dir for windows PC
tempFileDir: path.join(__dirname, './tmp'),
}),
);
then in your controllers, do this
const file = req.files.filename;
await file.mv(file.name);
if (!file || Object.keys(req.files).length === 0) {
return res.status(400).console.error('No files were uploaded.');
}
This solution is for non ejs and exporting modules solution:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>File Upload</title>
</head>
<body>
<form ref='uploadForm' encType="multipart/form-data" class="" action="/path/to/nodejs/upload/file" method="post">
<input type="file" name="my_file"><br>
<input type="submit" name="" value="upload">
</form>
</body>
</html>
Now here is the NodeJS
const express = require("express");
const app = express();
const fileUpload = require('express-fileupload');
app.use(fileUpload({ safeFileNames: true, preserveExtension: true }))
app.post('/', function(req, res) {
// The name of the input field (i.e. "sampleFile") is used to retrieve the uploaded file
let the_file = req.files.my_file;
the_file.mv('/path/to/html/uploads/up/' + the_file.name , function(err) {
res.writeHead(200, {"Content-Type": "text/plain"});
if(err){
console.log(err);
res.write(err);
res.end();
} else {
console.log("uploaded");
res.write("upload of file "+the_file.name+" complete");
res.end();
}
});
});
module.exports = app;
You have to create folder images!
//install path module
const path = require('path');
// remaining code
let startup_image = req.files.image;
startup_image.mv(path.resolve(__dirname,'/images',startup_image.name), function(error){
//remaining code
})
this way
file.mv(path.resolve(__dirname, '../public/images', filename)
I am trying to post the data from html form but it is showing an error "cannot POST".
This is my code:
controller/InquiryDetails.js:
var mongoose = require('mongoose'),
InquiryDetails = mongoose.model('InquiryDetails');
exports.add = function(req, res) {
InquiryDetails.create(req.body, function (error, details) {
if (error) return console.log(error);
return res.send(details);
});
}
routes/Inquiry.js
var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({extended:true}));
app.post('/InquiryDetails', function(req,res,err){
if(err) console.log(err);
res.json(req.body);
console.log(req.body);
});
module.exports = router;
model/InquiryDetails.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var myskyll = new Schema({
name: String,
email: String,
state: String,
country: String,
school: String,
profession: String,
phone: Number
});
mongoose.model('InquiryDetails', myskyll);
app.js:
var express = require('express');
var mongoose = require('mongoose');
var request = require('request');
var connect = require('connect');
var serveStatic = require('serve-static');
connect().use(serveStatic(__dirname+"/index.html")).listen(8080);
var mongoUri = 'mongodb://localhost/myskyll';
mongoose.connect(mongoUri);
var db = mongoose.connection;
db.on('error', function () {
throw new Error('unable to connect to database at ' + mongoUri);
});
var app = express();
console.log("connection successfull");
app.configure(function(req,res){
app.use(express.bodyParser());
});
app.use(express.static(__dirname + "/" ));
require('./models/InquiryDetails');
require('./routes/Inquiry');
app.listen(3000);
console.log('Listening on port 3000...');
index.html:
<form method="post" id="form1" action="InquiryDetails">
Your Name:<span class="imp">*</span><br/><input type="text"
name="name" placeholder="Firstname Lastname" class="textbox"
autofocus required pattern="[A-Za-z-0-9]+\s[A-Za-z-'0-9]+"
title="'Firstname' <space> 'Lastname'"/> <br/><br/>
Email:<span class="imp">*</span><br/><input
type="email" name="email" placeholder="Email" class="textbox"
required/><br/><br/>
city:<span class="imp">*</span><br/><input type="text" name="city"
placeholder="city" class="textbox" required/><br/><br/>
State/Country:<span class="imp">*</span><br/>
<input type="text" name="country"
placeholder="State/Country" class="textbox" required /><br/>
<br/>
School/Institution:<span class="imp">*</span><br/><input
type="text" name="school" placeholder="Your School or
Institution" c lass="textbox" required /><br/><br/>
Your Profession:<br/><input type="text" name="profession"
placeholder="Profession" class="textbox"><br/><br/>
Phone:<br/><input type="text" name="phone" placeholder="Phn. no.
with country code" class="textbox" pattern="\+[0-9]+" title="Only
digits" /><br/><br/>
<input type="submit" value="Submit"
class="btn3"/>
<input type="reset" value="Clear" class="btn3" />
</form>
I have tried in postman API client to post the data but it shows 404 status while posting the data.
Do I have any problem in my code?
Any suggestion will be appreciated!
You are creating multiple app objects. One in app.js and a different one in routes/Inquiry.js.
For this type of application, you will want to be using only one app object that you share with anyone who needs it because only one of them is actually registered with your web server and is being used.
That is likely why your app.post() handler is not working because it's registered on the wrong app object - the one that is not connected to a live server.
There are several other things that look incorrect in the code:
The third argument to an app.post() callback is a next() function reference, not the err that you have declared and are testing.
You are doing require('./models/InquiryDetails'); and that module exports some things, but you are not assigning the result of the require to anything so those exports are unusable.
You are initializing the connect module, but if you are using a recent version of Express that module is no longer needed as the functionality it used to provide for Express is now built into Express.