This question already has an answer here:
ExpressJS request body is empty if i don't use multer
(1 answer)
Closed 7 months ago.
I have a form with two numeric input fields that I'd like to send to the backend, but req.body is always empty. Here is my form:
<form
class="mt-3"
id="myForm"
enctype="multipart/form-data"
action="/submit-thing1and2"
>
<div class="mb-2">
<label for="thing1" class="form-label"
>Thing 1</label
>
<input
type="number"
class="form-control"
id="thing1"
name="thing1"
required
/>
</div>
<div class="mb-2">
<label for="thing2" class="form-label"
>Thing 2</label
>
<input
type="number"
class="form-control"
id="thing2"
name="thing2"
required
/>
</div>
<div class="form-group-row mb-3">
<button id="submitThings" type="submit" class="btn btn-primary">
Submit Things
</button>
</div>
</form>
I have tried using enctype="application/json", "text/html", and "application/x-www-form-urlencoded", and all of them still return an empty object in req.body.
Here is my post request:
form = document.getElementById("myForm");
form.addEventListener("submit", async (event, arg) => {
event.preventDefault();
console.log(event.target.action);
console.log(event.target);
let data = new FormData(event.target);
console.log(data.toString());
fetch(event.target.action, {
method: "post",
body: new FormData(event.target),
})
.then((res) => {
console.log(res.status);
return res.text();
})
.then((data) => {
console.log(data);
});
});
And here is my server-side handling of the post request - the console.log works, just shows an empty object:
const express = require("express");
const path = require("path");
const PORT = process.env.PORT || 5000;
const app = express();
app.use(express.static(path.join(__dirname)));
app.use(express.json());
app.use(
express.urlencoded({
extended: true,
})
);
app.post("/submit-thing1and2", async (req, res) => {
console.log("req.body", req.body);
res.send(req.body);
});
app.get("/", (req, res) => {
res.sendFile("./html/index.html", { root: __dirname });
});
app.listen(PORT, () => console.log(`Listening on ${PORT}`));
Use multer to parse multipart/form-data requests:
app.post("/submit-thing1and2",
multer().fields([{name: "thing1"}, {name: "thing2"}]),
async function(req, res) {
...
});
Related
I created a react, express app and then created a simple form in React app that accepts name and age and on submit the form data is supposed to go to backend express app and console log there but I can not access the form input data in my backend express.On submit I get this {"message":"Hello World"} logged in my console of react page.
//express app.js
const express = require('express');
const cors = require('cors');
const app = express()
app.use(cors())
app.use(express.urlencoded())
app.use(express.json())
app.use("/",(req,res)=>{
res.json({ message: "Hello World" });
})
app.post('/', (req, res) => {
const { fullname, age } = req.body;
console.log(fullname, age);
res.send('Form submitted successfully');
});
app.listen(5000,()=>{console.log("http://localhost:5000");})
My login react app:
import React from "react";
export default function App(){
function submitHandler(e){
e.preventDefault();
const fullname = e.target.elements.fullname.value;
const age = e.target.elements.age.value;
fetch('http://localhost:5000/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ fullname, age })
})
.then(response => response.text())
.then(data => {
console.log(data);
});
}
return (
<div className="App">
<form onSubmit={submitHandler}>
<input type="text" name="fullname" id="" placeholder="Name:" />
<input type="number" name="age" id="" placeholder="age" />
<input type="submit" value="Submit" />
</form>
</div>
);
}
Help me get the form input data in express app so that I can later store it in mongodb
You must replace app.use with app.get
app.get("/",(req,res)=>{
res.json({ message: "Hello World" });
})
see documentation of app.use
I'm trying to create a simple form which can upload file(pdf & image) and texts together using Node.js. Nonetheless, I don't wanna save the pdf file to MySql database, rather I want it to be kept in my internal storage "./uploads" folder. I have used npm formidable, mv, and multer, yet nothing works, anybody knows why?
Here's my html form
<form action="/auth/registerEvent" method = "POST">
<h5> Enter Your Event Information</h5>
<div class="form-group">
<label for="eventName">Event Name</label>
<input type="text" class="form-control" id="eventName" name="eventName" placeholder="Event Name">
</div>
<div class="form-group">
<label for="eventDescription">Description</label>
<textarea class="form-control" id="eventDescription" name="eventDescription" placeholder="Event Description: No more than 200 words" rows="3"></textarea>
</div>
<div class="form-group">
<label for="eventPoster">Poster</label>
<input type="file" class="form-control" id="eventPoster" name="eventPoster" enctype="multipart/form-data" accept=".jpg, .png, .jpeg">
</div>
<div class="form-group">
<label for="eventProposal">Sponsor Proposal</label>
<input type="file" class="form-control" id="eventProposal" name="eventProposal" enctype="multipart/form-data" accept=".pdf">
</div>
<br>
<button type="submit">Submit</button>
</form>
This is my app.js
const express = require('express');
const path = require('path');
const app = express();
const mysql = require('mysql');
const dotenv = require('dotenv');
dotenv.config({path: './.env'}); // connect to .env
// set views folder
app.set('view engine', 'html');
app.engine('html', require('hbs').__express);
// set the directory to css and js
const publicDirectory = path.join(__dirname, './public');
app.use(express.static(publicDirectory));
// Parse URL encoded bodies (as sent by HTML Form)
app.use(express.urlencoded({extended: false}));
// Parse JSON bodies (as sent by API clients)
app.use(express.json());
// Define routes
app.use('/', require('./router/pages.js'));
app.use('/auth', require('./router/auth.js'));
// connect to mysql
const db = mysql.createConnection({
host: process.env.LOCALHOST,
user: process.env.USER,
password: process.env.PASSWORD,
database: process.env.DATABASE,
});
db.connect( (err) => {
if (err) console.log(err);
else console.log('Database is connected');
} )
// laptop server
app.listen(3000, (req, res)=>{
console.log('Server is running at localhost:3000');
});
and finally the "auth.js"
const formidable = require('formidable');
const fs = require('fs');
const mysql = require('mysql');
const db = mysql.createConnection({
host: process.env.LOCALHOST,
user: process.env.USER,
password: process.env.PASSWORD,
database: process.env.DATABASE,
});
exports.registerEvent = (req, res) => {
const {
eventName, eventInstitution,
// eventStartDate, eventEndDate,
eventAddress, eventDescription,
eventPoster, eventProposal,
// eoName, eoPhone, eoEmail
} = req.body;
if (req.url === "/registerEvent") {
const form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
const oldPath = eventPoster.path;
const newPath = './uploads' + eventPoster;
fs.rename(oldPath, newPath, function (err) {
if (err) throw err;
});
})
}
// db start
db.query('INSERT INTO registerevent SET ? ', {
EventName: eventName,
Institution: eventInstitution,
// StartDate: eventStartDate,
// EndDate: eventEndDate,
Address: eventAddress,
Description: eventDescription,
// Poster: eventPoster,
// Proposal: eventProposal,
// ContactName: eoName,
// PhoneNumber: eoPhone,
// Email: eoEmail,
}, (error, result) => {
if (error) { console.log(error); }
else {
res.statusCode = 302;
res.setHeader("Location", "/feedback");
res.end();
}
});
// db end
}
So when the customer enters the name & address it goes to sql, and the poster and proposal files will be sent to my "/uploads" directory. Please help
So, I am using Node.js with express to run a server and make a calculator. After that, I downloaded body-parser, to get the access of the numbers the user inputs and use it to calculate the result, but for some reason whenever I try to log one of the numbers on console, just to make sure that it works, it doesn't get logged.
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({extended: true}));
app.get('/', (req, res) => {
res.sendFile(`${__dirname}/index.html`);
})
app.post('/', (req, res) => {
console.log(req.body);
res.send('Thanks for the information');
})
app.listen(3000, () => console.log('Server Started'));
Your form will look something like this
<form id="post-form" action="/your/post/url" method="POST">
<div class="form-control">
<label for="title">Number</label>
<input type="number" name="number" id="number">
</div>
<button type="submit">
Submit
</button>
</form>
Or in your script tag, you can do something like this.
with this approach, the form gets submitted without reload
// Note: Optional approach (without reloading the page)
// Just above HTML only code also works perfectly fine
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
const number= document.getElementById('number')
document.getElementById('post-form').addEventListener('submit', (e) => {
e.preventDefault();
axios
.post('/your/post/url', { number: number.value })
.then((res) => {
//handle response here
})
.catch((err) => { //handle err here});
});
<script>
then in you express app you can do
app.post('/you/post/url/', (req,res,next) => {
// this is how you accces title from you form
// here title will hold value "Value Here"
const { number} = req.body
//calculate here
number = number * number + number
// then send the response
res.send(`calculated number: ${number}`)
});
I am a beginner to react and node and this will be a very basic problem.
I am creating a basic react fronted with a node backend. I setup mysql database connection and all set. I want to insert user details using /createUser api call to store data to database.
I run the server/app.js, react serve and index.js which contained my listener for /createUser.
When I input username,password using my form, empty req.body object will be returned in express.post method while I am expecting the username and password I entered.
In other case, when I start the listener, react front is not loading by giving the error below.
GET http://localhost:3000/%PUBLIC_URL%/manifest.json 404 (Not Found)
manifest.json:1 Manifest: Line: 1, column: 1, Unexpected token.
It seems like node component cannot access my manifest file. Am I correct?
index.js
const express = require('express');
const bodyParser = require('body-parser');
const store = require('./store');
const app = express();
app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json({ type: 'application/*+json' }));
app.use(bodyParser.json());
app.post('/createUser', (req, res) => {
console.log(req.body);
store
.createUser({
username: req.body.username,
password: req.body.password
})
.then(() => res.sendStatus(200))
})
app.listen(3001, () => {
console.log('Server running on http://localhost:3001')
})
login.js
import React, { Component } from 'react';
import classes from './Login.css';
function post (path, data) {
console.log(data);
return window.fetch(path, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
}
function handleLoginClick(e) {
e.preventDefault();
console.log('The link was clicked.');
const Login = document.querySelector('.Login');
const username = Login.querySelector('.username').value;
const password = Login.querySelector('.password').value;
post('/login', { username, password })
.then(({ status }) => {
if (status === 200) alert('login success')
else alert('login failed')
})
}
function handleSignupClick(e) {
e.preventDefault();
console.log('The link was clicked sign up.');
const CreateUser = document.querySelector('.CreateUser')
const username = CreateUser.querySelector('.username').value;
const password = CreateUser.querySelector('.password').value;
post('/createUser', { username, password })
}
class Login extends Component {
componentDidMount() {
}
componentWillUnmount() {
}
render() {
return (
<div>
<form className="Login">
<h1>Login</h1>
<input type="text" className="username" placeholder="username"/>
<input type="password" className="password" placeholder="password"/>
<input type="submit" value="Login" onClick={handleLoginClick}/>
</form>
<form className="CreateUser">
<h1>Create account</h1>
<input type="text" className="username" placeholder="username"/>
<input type="password" className="password" placeholder="password"/>
<input type="submit" value="Create" onClick={handleSignupClick}/>
</form>
</div>
);
}
}
export default Login;
What's wrong with my code? Can someone please explain me.
my code : https://github.com/indunie/tms2
Try to replace bodyParser configuration to following lines of code:
app.use(bodyParser.json({ limit: '100mb' }));
app.use(bodyParser.urlencoded({ limit: '100mb', extended: false }));
This might help you
solved [https://github.com/expressjs/express/issues/3881][1]
There are two solutions here:
Change the URL to http://localhost:3001/manifest.json to match how you have express.static setup.
Change express.static to app.use('/public', express.static('public')); such that http://localhost:3001/public/manifest.json will refer to the given file.
I'm using Node.Js and express framework for my application.
I build HTML forms and upon submitting I'm not able to receive my form data on API request.
My HTML:
<form method="post" action="/create">
<input type="text" name="user.name" />
<input type="text" name="user.email" />
<input type="text" name="user.address.city" />
<input type="text" name="user.address.land" />
<input type="submit" value="Submit">
</form>
JSON object should been obtained at my API:
{
"user": {
"name": "toto",
"email": "toto#mail.com",
"address": {
"city": "yyyyy",
"land": "zzzz"
}
}
}
How to do this with Node.js, Express 4 and is there another library for this?
You can prepare your own middleware that parses the incoming form data using body-parser's urlencoded() and turns it into a structured JSON:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
function setDeepValue(path, obj, value) {
const tokens = path.split('.');
const last = tokens.pop();
for (const token of tokens) {
if (!obj.hasOwnProperty(token)) {
obj[token] = {};
}
obj = obj[token];
}
obj[last] = value;
}
app.use(bodyParser.urlencoded(), function(req, res, next) {
let obj = {};
for (const key in req.body) {
setDeepValue(key, obj, req.body[key]);
}
req.body = obj;
next();
});
app.post('/create', function(req, res) {
console.log(req.body)
})
In your HTML code you are posting to a create route.
So in express you need to create that route
const express = require('express')
const bodyParser = require('body-parser')
const app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.post('/create', function(req, res) {
console.log('----- MY BODY -----')
console.log(req.body)
// do something more clever
res.send('We posted to this route')
})
First we require express, then we require body-parser and finally initialize our express app.
We then use the json middlewere of body-parser to parse the body so that we can easily access it in our handler.
We then define a route to '/create' that accepts posts request (remember that your form is posting to this location).
All that our handler does is to console.log the body of the request, and then shows the message We posted to this route
Follow this guide repository specially created to guide freshers nodejs-frontend-sample-for-freshers
EDIT:
You can use Ajax call to submit form this will also help in Single Page Application
Client-side JS:
function submit() {
// JavaScript uses `id` to fetch value
let email = $("#email").val(),
name = $("#name").val(),
city = $("#city").val(),
land = $("#land").val();
// Can validate each field here and show error like:
if ( validateEmail(email) ) {
$("#emailError").addClass("hide");
} else {
$("#emailError").removeClass("hide");
return;
}
// form request data, doing this will get you data in correct form at NodeJs API
let data = {
user: {
email,
name,
address: {
city,
land
}
}
};
$.ajax({
"url": "/create",
"method": "POST",
"data": data
})
.then( result => {
// On success empty all the input fields.
$("#email").val('');
$("#name").val('');
$("#city").val('');
$("#land").val('');
// Message to notify success submition
alert("Successfully added user.");
return;
})
.catch( err => {
// Notify in case some error occured
alert("An error occured.");
return;
});
}
// Validate Email based upon pattern
function validateEmail (email) {
if ( email && email.match(/^([A-z0-9_.]{2,})([#]{1})([A-z]{1,})([.]{1})([A-z.]{1,})*$/) ) {
return true;
}
return false;
}
HTML:
<form>
<input type="text" id="name" />
<input type="text" id="email" />
<span id="emailError" class="hide error">Valid Email Required</span>
<input type="text" id="city" />
<input type="text" id="land" />
<p onclick="submit()">Submit</p>
</form>
Would recommend you to use cors.js too like:
const cors = require('cors');
// Cross-Origin Resource Sharing
app.use(cors());
You can get object in two ways:
1: Using no extra module something like this
app.post('/create', function (request, response, next) {
let body = [];
request.on('error', (err) => {
console.error(err);
}).on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
console.log(body); // Your object
request.body = body; // Store object in request again
next();
});
}, (req, res) => {
console.log(req.body); // This will have your object
});
Using body-parser with express:
```
// configure the app to use bodyParser() to extract body from request.
// parse urlencoded types to JSON
app.use(bodyParser.urlencoded({
extended: true
}));
// parse various different custom JSON types as JSON
app.use(bodyParser.json({ type: 'application/*+json' }));
// parse some custom thing into a Buffer
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }));
// parse an HTML body into a string
app.use(bodyParser.text({ type: 'text/html' }));
app.post('/create', function (request, response, next) {
console.log(request.body); // `body-parser did what I did earlier`
});
```