req.body is blank in POST requests (Express node) - node.js

Server Code:
const express = require('express')
const app = express() app.use(express.static('public')) app.use(express.json({limit :'100mb'}));
app.post('/post', (req, res) => { console.log('post called');
console.log(req.body); ////Printed here
})
app.listen(3000)
Client code:
const data ={agent: 41}
const options = {
method: 'POST',
mode: 'no-cors',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
};
fetch('http://localhost:3000/post', options);
output in server terminal
can anyone please tell me what am i doing wrong, how can i get the value?
Expected Output :
{agent: 41}

On you client code, why are you using mode: 'no-cors' option?
Removing it will fix your problem.
const data = { agent: 41 }
const options = { method: 'POST', credentials: 'same-origin', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) };
fetch('http://localhost:3000/post', options);
Here you can find an explaination on what is happening.
If you were using mode: 'no-cors' to handle a cors error, this is not the way to go. You should use the cors middleware in you Express based application.
const express = require('express')
const cors = require('cors')
const app = express()
app.use(cors()) // use it as first middleware

Related

React Native post to Node.js/Express

I am triying to make a post query from my React Native (expo) app to Node.js server (express). And the post is doing nothing. Even, console.log doesnot work. Please, need your help with this
React Native App code:
const options = {
method: 'POST',
timeout: 20000,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json;charset=UTF-8'
},
body: JSON.stringify({
a: 10,
b: 20
})
};
fetch(url, options)
.then(response => {
console.log(response.status);
})
.catch(error => console.error('timeout exceeded'));
console.log('3232');
And node.js code:
var express = require('express');
/// create express app
var app = express();
app.use(express.json());
app.post('/g_data/auth', function(req, res){
console.log('LOGGED')
res.send('Hello World!')
});
React Native console return : "3232"
node.js console return nothing
No "new incoming connection detected from ...", "LOGGED", as expected.
Please help, what I am doing wrong?
maybe u need to install and import body-parser on your node js
var express = require('express');
var bodyParser = require('body-parser'); // ++
/// create express app
var app = express();
app.use(express.json());
app.use(bodyParser.urlencoded({extended: false})); // ++
app.post('/g_data/auth', function(req, res){
console.log('LOGGED')
res.send('Hello World!')
});
Ok! the final solution is in wrong Headers. For some reasons, React Native app send Headers:
'Content-Type': 'application/json;charset=UTF-8'
But node.js server receives:
'Content-Type': 'text/plain;charset=UTF-8'
So, first, I have installed cors to server, npm i cors -save and for some reason left Body Parser, and a little bit modernize headers. Here is a final code:
React Native App:
let formdata = '["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]';
///console.log(formdata);
const url = 'http://192.168.88.15:7935/g_data/auth';
const options = {
method: 'POST',
timeout: 20000,
mode:'cors',
headers: {
'Content-Type': 'application/json; charset=utf-8',
},
body: formdata
};
fetch(url, options)
.then((response) => response.json())
/// make design
setLoading(false);
/// next code
console.log('next!');
The server code is:
var express = require('express');
var cors = require('cors')
var bodyParser = require('body-parser');
/// create express app
var app = express();
/// use cors
app.use(cors())
/// use body req parser
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.post('/g_data/auth', function(req, res){
console.log(req.body)
res.send({Message: 'Hello World!'})
});
app.listen(7935);
console.log('listen port 7935');

Can't make a successful Authorization request from Axios request to third-party API

I have been dealing with this issue where I am attempting to make a get request to a third-party API using Axios in my Node.js server. The endpoint requires a username and password which I am passing along as follows:
export const getStream = async(req, res) => {
let conn = createConnection(config);
let query = `SELECT * FROM cameras WHERE id = ${req.params.id}`
conn.connect();
conn.query(query, async (error, rows, _) => {
const camera = rows[0];
const {ip, user, pass} = camera;
if (error) {
return res.json({ "status": "failure", "error": error });
}
const tok = `${user}:${pass}`;
const userPass = Buffer.from(tok)
const base64data = userPass.toString('base64');
const basic = `Basic ${base64data}`;
const result = await axios({
method: 'get',
url: `<API URL>`,
headers: {
'Authorization': basic,
'Content-Type': 'multipart/x-mixed-replace; boundary=--myboundary'
},
auth: {username: user, password: pass}
})
res.json(result)
});
conn.end();
}
I am then calling this endpoint in my React front-end as such:
const getStream = async () => {
try {
const result = await publicRequest.get(`camera/getStream/${id}`)
console.log(result)
} catch (error) {
console.error(error)
}
}
Each time I make this request, my node server crashes and I get a 401 unauthorized error in my console. It appears that my Authorization header is not getting passed to the server even though everything else gets passed along as so.
headers: {
Accept: 'application/json, text/plain, */*',
'Content-Type': 'multipart/x-mixed-replace; boundary=--myboundary',
'User-Agent': 'axios/0.26.1'
},
method: 'get',
url: '<url>',
auth: { username: '<username>', password: '<password>' },
data: undefined
For extra information, this is how my node server is setup
import express, { urlencoded, json } from 'express';
import userRoute from './routes/userRoute.js';
import cameraRoute from './routes/cameraRoute.js';
import cors from 'cors';
const app = express();
app.use(cors());
app.options('*', cors());
app.use(json())
app.use(urlencoded({ extended: true }));
app.use(express.static('public'));
app.use('/api/user', userRoute);
app.use('/api/camera', cameraRoute);
const port = process.env.PORT || 8080;
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
I have been working on this issue for several days and each time I try something new, I always get a 401 error, and the server crashes.
Any suggestions would be greatly appreciated.

How to read formdata in nodejs

I'm using ionic angular in frontend and I' trying to send a formdata that contains a file and also 2 strings. Apparently its being sent however I don't know how to read that information on the server side
FRONTEND
private fil3: File;
changePicture(fileChangeEvent){//this functions is called by an input file
this.fil3 = fileChangeEvent.target.files[0];
let a1 = "a1"
let a2 = "a2"
let b1 = "b1"
let b2 = "b2"
let formData = new FormData();
formData.append('photo', this.fil3, this.fil3.name);
formData.append(a1, a2);
formData.append(b1, b2);
fetch('http://localhost:3000/up', {
method: 'POST',
body: formData,
headers:{
/* 'Content-Type': 'application/json' */
'Content-Type': "multipart/form-data"
},
mode: "cors",
}).then(res =>{ res.json().then((data)=>{
console.log("filename: "+data.filename);
console.log("originalname: "+data.originalname);
console.log("message: "+data.message);
this.avatar="../../assets/uploads/"+data.filename
})
})
.catch(error => {console.error('Error:', error)})
.then(response => {console.log(response)});
}//changePicture
SERVER
function updatePicture (req, res) {
console.log("req.body: "+req.body)
}
On the server side I'm just trying to read each element of the formdata individually so I can work with them. These elements are the file and two other strings(a1,a2,b1,b2). This console.log on the server prints this req.body: [object Object]
I tried things like
console.log("req.body: "+req.body.a1)
console.log("req.body: "+req.body.[1])
but certainly do not work, I get undefined, I have no idea how to handle this, any word of advice?
MINIMUN REPRODUCIBLE CODE OF BACKEND
const express = require ('express')
const bodyParser = require ('body-parser')
const app = express()
const api = express.Router()
const cors = require('cors')
app.use(bodyParser.urlencoded({ extended:false}))
app.use(bodyParser.json())
app.use(cors({
origin: true
}));
const PORT = 3000;
app.listen(config.port, ()=>{
console.log(`Server running on port: ${PORT}`)
})
api.post('/up', (req, res) =>{
console.log(req.body)
})
Firstly, remove this part :
headers:{
/* 'Content-Type': 'application/json' */
'Content-Type': "multipart/form-data"
}
because if you define Content-Type manually, you can't inform about boundary information. It need to managed automatically by browser because you send files too.
Secondly, you need a library to parse you're multi-part data. You can use formidable :
const formidable = require('formidable');
//You're other codes
app.post('/up', (req, res) => {
const form = formidable({ multiples: true });
form.parse(req, (err, fields, files) => {
console.log('fields: ', fields);
console.log('files: ', files);
res.send({ success: true });
});
});
For my side this log something like :
fields: { a1: 'a2', b1: 'b2' }
files: {
file: PersistentFile {
...

Express JS is receiving an empty req.body from ReactJS

I am currently having a problem with React and Express JS form submit function. It seems like my nodeJS running on port 5000 is receiving an empty object from my ReactJS running on port 8080 using fetch method.
React : Contact.js
handleSubmit(e)
{
e.preventDefault();
var data = {
name: this.state.name,
contact: this.state.contact,
email: this.state.email,
message: this.state.message,
}
var url = 'http://localhost:5000/api/insertUsers';
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
mode: 'no-cors',
body: JSON.stringify(data),
})
.catch((error) => {
console.log(error);
});
}
NodeJS : server.js
const express = require('express');
const { Client } = require('pg');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.post('/api/insertUsers', function(req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:\n')
res.end(JSON.stringify(req.body, null, 2))
});
app.listen(5000, () => {
console.log('listening on port 5000');
});
Change the order of bodyparser middleware like this.
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
You are sending a request with the content-type of 'application/json' but express is expecting a content-type of 'text/json'. Usually, when req.body is empty content-type is the first suspect you should be looking at.
I am ashamed that I struggled with this for hours. I still haven't gotten it to work with file uploads.
But I did get it to work with a normal form by encoding JSON and sending that along with axios, instead of fetch
My js code
var data = {
id: this.state.id,
}
console.log('data',data)
var bodyFormData = new FormData();
bodyFormData.set('id', this.state.id);
var url = ' http://localhost:3000/get-image-by-id';
console.log("bodyFormData: ", bodyFormData);
axios({
method: 'post',
url: url,
data: data,
// headers: {'Content-Type': 'multipart/form-data' }
headers: {'Content-Type': 'application/x-www-form-urlencoded' }
})
.then(function (response) {
//handle success
console.log(response);
})
.catch(function (response) {
//handle error
console.log(response);
});
Form Code
<form method="POST" onSubmit={this.handleSubmit} >
<label>
Transaction ID
<input
type="text"
name="id"
value={this.state.id}
onChange={this.handleInputChange}
/>
</label>
<button type="submit">Submit</button>
</form>
```
EDIT
fetch(url, {
method: 'POST',
body: JSON.stringify(data),
mode: 'no-cors'
}).then((result)=>{
console.log("output" + result.json());
})
.catch((error) => {
console.log(error);
});
EDIT 2
for backend, install cors and add the following lines before route.
var cors = require('cors')
app.use(cors())
EDIT 3
perform npm install morgan then copy these lines inside the code
var morgan = require('morgan');
app.use(morgan('dev'));
I didn't look at your code close enough. My bad
app.post('/api/insertUsers', function(req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:\n')
res.end(JSON.stringify(req.body, null, 2))
});
Should be
app.post('/api/insertUsers', function(req, res) {
res.json(req.body)
});
try using axios instead of fetch
I rewrote ur code like this and it works perfectly
server
const express = require('express');
const { Client } = require('pg');
const bodyParser = require('body-parser');
const app = express();
const cors = require("cors");
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.post('/api/insertUsers', function(req, res) {
// console.log(req);
console.log(req.body);
res.send(req.body);
});
app.listen(3001, () => {
console.log('listening on port 3001');
});
react (ensure you have axios installed)
handleSubmit(e){
e.preventDefault();
var data = {
name: "zadiki",
contact: "0702002109",
email: "zadiki",
message: "test",
}
console.log("wow");
var url = ' http://localhost:3001/api/insertUsers';
axios.post(url,data)
.then(response=>console.log(response))
.catch(e=>console.log(e))
}
Hello I ended up getting mine working after I ran into the same problem.
I noticed your react code has "mode: 'no-cors'," that was causing problems with mine so I removed it.
-------- Below is my handle submit code for React ------------
const handleSubmit = (event) => {
event.preventDefault();
const url = "http://localhost:3001/register"
const options = {
method: "POST",
body: JSON.stringify(formData),
headers: {
"Content-Type": "application/json"
}
}
fetch(url, options)
.then(res => res.json())
.then(res => console.log(res))
}
I used express.json instead of bodyParser. You also had a typo in your express code, it should say res.send instead of res.end
--------- Below is my Node Express Code -----------
const express = require('express');
const app = express();
const cors = require('cors');
const multer = require('multer');
// Middlewares
app.use(cors({ origin: 'http://localhost:3000', }))
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use(multer().array());
app.post('/register',(req, res) => {
console.log(req.body)
res.status(200)
.json({status:"Success", data:{body: req.body })
});
app.listen(3001, () => console.log(`Running on 3001`))
I was able to send form data using postman and react using the code above. Feel free to change it to accommodate your needs.

cant get req object in post fetch

Code of the node.js program:
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser')
var app = express();
var cors = require('cors');
app.use(express.static(path.join(__dirname,'../client/' ,'build')));
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.use(cors());
app.post('/',(req,res)=>{
console.log(req.body); //always empty
})
I think the node.js program is right but every time front-end application hits the url req.body is always empty and I don't know why.
My front-end application is built with React.js and below is the code where I call the fetch().
fetch('/', {
method: 'POST',
body: JSON.stringify({
task: details
}),
headers: {
"Content-Type": "application/json"
}
})
Try changing couple things:
In your frontend:
fetch('/', {
method: 'POST',
body: { task: details },
headers: { "Content-Type": "application/json" }
})
In your server side:
app.post('/',(req,res)=>{
console.log(JSON.stringify(req.body)); //always empty
})
This should works.

Resources