I am creating an app using Node, Express and ejs and multer for uploading images. Every time I submit the form, req.file is undefined. I've spent the entire day troubleshooting but can't figure out what I'm doing wrong.
HTML
<form action="/post" id="formPost" method="post" enctype="multipart/form-data">
<input class="img-file" type="file" name="image" required>
<input class="submit" type="submit" value="Post" />
</form>
app.js
const path = require('path');
const express = require('express');
const morgan = require('morgan');
const bodyParser = require("body-parser");
const multer = require('multer');
const app = express();
app.use(express.static(path.join(__dirname, 'public')))
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname,'resources/views'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "./image");
},
filename: function (req, file, cb) {
console.log(req.file);
cb(null, Date.now() + "-" + file.fieldname + ".png");
},
});
const upload = multer({ storage: storage });
app.post("/post", upload.single("image"), (req, res) => {
console.log(req.file);
});
app.get("/post", (req, res) => {
res.render("post");
});
app.listen(, () => {
console.log(`Example app listening at http://localhost:3000/login`);
});
You have few little bugs: first you forgot to add port and instead of login it should be post then we hit the correct address immediately, avoiding error Cannot GET /login
app.listen(3000, () => {
console.log(`Example app listening at http://localhost:3000/post`);
});
Project Folder & File structure:
app.js I added simple an error handler to the:
app.post("/post", upload.single("image"), (req, res, next) => {}
const path = require("path");
const express = require("express");
const morgan = require("morgan");
const bodyParser = require("body-parser");
const multer = require("multer");
const app = express();
app.use(express.static(path.join(__dirname, "public")));
app.set("view engine", "ejs");
app.set("views", path.join(__dirname, "resources/views"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "./image");
},
filename: function (req, file, cb) {
console.log(req.file);
cb(null, Date.now() + "-" + file.fieldname + ".png");
},
});
const upload = multer({ storage: storage });
// app.post("/post", upload.single("image"), (req, res) => {
// console.log(req.file);
// });
app.post("/post", upload.single("image"), (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);
console.log("Success", req.file);
});
app.get("/post", (req, res) => {
res.render("post");
});
app.listen(3000, () => {
console.log(`Example app listening at http://localhost:3000/post`);
});
post.ejs
<form action="/post" id="formPost" method="post" enctype="multipart/form-data">
<input class="img-file" type="file" name="image" required />
<input class="submit" type="submit" value="Upload File" />
</form>
output:
after selecting the file and pressing upload file:
VSCode output:
Works like a charm ;-)
Related
I'm trynna get the form`s data that contains a file, and I use Multer for handling that, but for some reason, my req.body is returning {}, but when I use the normal form without multipart data, it gives me all the data, so the problem is with Multer, here's my code
const express = require("express");
const app = express();
const multer = require("multer");
app.listen(8000);
let upload = multer({ dest: "uploads/" });
upload.single("logo");
app.use(express.urlencoded({ extended: true }));
app.post("/", (req, res) => {
console.log(req.file);
});
const express = require("express");
const app = express();
const multer = require("multer");
app.listen(8000);
let upload = multer({ dest: "uploads/" });
app.use(express.urlencoded({ extended: true }));
app.post("/", upload.single("logo"), (req, res) => {
console.log(req.file);
});
You need to specify upload.single as middleware.
This is working code in my project.
const path = require("path");
const multer = require('multer');
const fileStorage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'images');
},
filename: (req, file, cb) => {
cb(null, new Date().toISOString()+ "-" + file.originalname);
}
});
const fileFilter = (req, file, cb) => {
if (
file.mimetype === 'image/png' ||
file.mimetype === 'image/jpg' ||
file.mimetype === 'image/jpeg'
) {
cb(null, true);
} else {
cb(null, false);
}
};
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
app.use(multer({ storage: fileStorage, fileFilter: fileFilter }).single('image'));
app.use(express.static(path.join(__dirname, 'public')));
app.use("/images", express.static(path.join(__dirname, 'images')));
app.post("/", (req, res) => {
console.log(req.file);
});
app.listen(5000, () => console.log("Server Started!"));
I tried two middlewares but still getting this output in the terminal:
{}
my node js server code:
express = require('express');
bodyParser = require('body-parser');
const app = express();
//the middlewares i tried
app.use(express.urlencoded({extended: false}));
app.use(bodyParser());
app.get('/', (req, res) => {
res.sendFile(__dirname + '/client.html');
});
app.post('/test', (req, res) => {
res.send('this is a test path');
console.log(req.body);
});
app.listen(3000, () => {
console.log('server listening...');
});
my form (client.html file):
<form method="POST" action="/test">
<input type="text">
<input type="submit">
</form>
I also tried send the post data with postman. I know that the action in the html form is working because I can see the "this is a test path" output in the browser
try this
express = require('express');
bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.get('/', (req, res) => {
res.sendFile(__dirname + '/client.html');
});
app.post('/test', (req, res) => {
res.send('this is a test path');
console.log(req.body);
});
app.listen(3000, () => {
console.log('server listening...');
});
also in html form , add name property in input tag
<form method="POST" action="/test">
<input type="text" name="email">
<input type="submit">
</form>
in fact it works just like
app.use(express.urlencoded());
the wrong thing was the nameless input in the html form
you should write code like this
var app=express();
app.use(bodyparser.urlencoded({ extended: true }));
app.use(bodyparser.json());
app.post('/test', (req, res) => {
console.log(req.body.email);
res.send('this is a test path'+req.body.email);
});
I'm trying ti deploy a NodeJS App to Azure. Everything works fine including react. but when I'm trying to hit the GraphQL server I'm getting a 404 Error
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
Any Ideas?
Here is my index.js
'use strict'
require('babel-core/register')
import schema from './data/schema'
import GraphQLHTTP from 'express-graphql'
import express from 'express'
const multer = require('multer')
const insert = require('./business/insert')
const app = express()
const port = process.env.PORT || 8080
var bodyParser = require('body-parser')
app.use(bodyParser.json()) // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })) // support encoded bodies
app.use('/graphql', GraphQLHTTP({
schema,
graphiql: true
}))
app.use(express.static('public'))
app.set('view engine', 'html')
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public/upload/')
},
filename: function (req, file, cb) {
cb(null, Date.now() + '.xlsx')
}
})
var upload = multer({ storage: storage })
app.get('/', (req, res) => {
res.render('index')
})
app.listen(port, () => {
console.log('Listening http://localhost:8080')
})
Judging by this document https://babeljs.io/docs/usage/require/ it appears that tooling for ES6 only happens via the next requires
All subsequent files required by node with the extensions .es6, .es, .jsx and .js will be transformed by Babel.
So you'll need something like this instead:
// app.js
'use strict'
require('babel-core/register')
require('./index')
// index.js
import schema from './data/schema'
import GraphQLHTTP from 'express-graphql'
import express from 'express'
const multer = require('multer')
const insert = require('./business/insert')
const app = express()
const port = process.env.PORT || 8080
var bodyParser = require('body-parser')
app.use(bodyParser.json()) // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })) // support encoded bodies
app.use('/graphql', GraphQLHTTP({
schema,
graphiql: true
}))
app.use(express.static('public'))
app.set('view engine', 'html')
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public/upload/')
},
filename: function (req, file, cb) {
cb(null, Date.now() + '.xlsx')
}
})
var upload = multer({ storage: storage })
app.get('/', (req, res) => {
res.render('index')
})
app.listen(port, () => {
console.log('Listening http://localhost:8080')
})
I have following code for uploading image and handling text input. But both are not working together
*Images are uploading properly but I can't get text field value *
var express = require('express');
var multer = require('multer');
var mime = require('mime');
var app = express();
var 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.get('/completeForm.html', function(req, res){
res.sendFile(__dirname + '/' + 'completeForm.html')
});
app.post("/postFormAct", function (req, res, next) {
console.log(req.body.user); // Here i getting undefined
console.log(req.body.email);// Here i getting undefined
upload(req,res,function(err) {
console.log(req.files); // Here i getting proper output and image also uploading to concern folder
});
});
app.listen(3000);
Html code given below.... please help me someone
<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>
Just put
console.log(req.body.user);
console.log(req.body.email);
inside your upload function. After the function may also work.
That's because there is no multipart/form-data parsing middleware called before your /postFormAct route handler.
You have two parsing middlewares set up but not one of them parse this multipart/form-data Content-Type.
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
Multer does that, so you can access req.body.user and req.body.email variables in handlers following your upload middleware.
when i run this app and submit the form 'console.log(request.body)' returning undefined. i am a beginner in node js . can anyone please explain what i am doing wrong?
this is the registration form
register.jade
doctype html
html
head
title.
Fonebook
link(rel='stylesheet', href='/assets/bootstrap/css/bootstrap.min.css')
script(src='https://code.jquery.com/jquery-2.2.0.min.js')
script(src='/assets/bootstrap/js/bootstrap.min.js')
body
div.container
h3.
The Fonebook
form(method="POST",class="center",id="regForm",action='/doReg',enctype="multipart/form-data")
div.panel.panel-info
div.panel-heading.
Registration
div.panel-body
div.col-md-offset-3.col-md-6.col-md-offset-3.form-group
label.
Profile Picture:
input(type='file',name='proPic')
div.col-md-offset-3.col-md-6.col-md-offset-3.form-group
label.
Email:
input.form-control(id="email", type="email", name="email", placeholder="Enter email ")
div.col-md-offset-3.col-md-6.col-md-offset-3.form-group
label.
Name:
input.form-control(id="name", type="text", name="name", placeholder="Enter name ")
div.col-md-offset-3.col-md-6.col-md-offset-3.form-group
label.
Password:
input.form-control(id="password", type="password", name="password")
div.col-md-offset-3.col-md-6.col-md-offset-3.form-group
a(href='login').
Already have an account?
div.panel-footer
button.btn.btn-info(type="submit").
Register
here is my app.js file
var express = require('express');
var app = express();
var mongoose = require('mongoose');
mongoose.connect('mongodb://127.0.0.1/test');
var uploadDir = __dirname + '/uploads';
var fs = require('fs');
var multer = require('multer');
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
var conn = mongoose.connection;
app.set('views', './views');
app.set('view engine', 'jade');
app.use('/assets', express.static(__dirname + '/public'));
var port = process.env.PORT || 3000;
app.all('/', function (req, res) {
res.render('login');
})
app.all('/register', function (req, res) {
res.render('register');
})
app.all('/login', function (req, res) {
res.render('login');
})
var storage = multer.diskStorage({
destination: function (request, file, callback) {
callback(null, uploadDir);
},
filename: function (request, file, callback) {
//console.log(file);
callback(null, Date.now() + '.jpg');
}
});
var upload = multer({storage: storage}).single('proPic');
app.all('/doReg', function (request, response) {
upload(request, response, function (err) {
if (err) {
console.log(err);
return;
}
//console.log(request.file);
response.end('Your File Uploaded');
})
console.log(request.body);
});
app.listen(port);
body-parser does not support multipart forms.
From their README
This does not handle multipart bodies, due to their complex and typically large nature. For multipart bodies, you may be interested in the following modules:
busboy and connect-busboy
multiparty and connect-multiparty
formidable
multer
Seeing as you're already using multer you can access your fields this way:
app.all('/doReg', upload, function (request, response) {
console.log(request.body);
});