ajax requests to Node.js - node.js

In my app.js file in Node.js I have this:
app.use(express.json());
which I thought was good enough but whenever I submit data via jQuery/Ajax the response is an empty object.
After doing the below however, it now get the data from req.body. But, I thought that in the newer versions of Express it was not necessary to do this anymore?
const bodyParser = require("body-parser");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
The Ajax request:
$.ajax({
url: 'http://localhost:8000/api/v1/endpoint',
method: 'POST',
data: {key: key}
})
.done(function(data) {
console.log(data)
})
.fail(function(data) {
console.log(data);
})

The issue is with how you're making your ajax requests. express.json expects the Content-Type of the request to be JSON and I believe if you check your network call on the browser DevTools you'll see that the Content-Type of your request is not JSON.
You need to set the headers in your ajax request and also send valid JSON data like so
headers: {
'Content-Type': 'application/json',
},
data: JSON.stringify({key: key})
Then the express.json middleware will handle the request and you won't need to use the bodyParser lines of code you're using.

Related

No session value stored after assigning a value to session nodejs (express-session) n react front

I am having issue storing a value in the nodejs express sessions.
app.post('/validate',async(req,res)=>{
var users =new lib.UsersMain();
var userRes=await users.UserData(req.body.email,req.body.password);
if(userRes.id!='email_err' && userRes.id!='pass_err'){
req.session.user_id=userRes.id;
}
res.json({msgs:userRes.id});
})
app.post('/allusersdata',async(req,res)=>{
var users =new lib.UsersMain();
console.log(req.session.user_id);
var allUsers=await users.userDatamain(req.body.userId)
res.json({allUsers})
})
This is the code i have used to store and print a "session stored value".
*first post request sets a value in the session as the second one prints when a post request made
app.use(cors({
origin: 'http://192.168.0.144:3000',
methods: ['POST', 'PUT', 'GET', 'OPTIONS', 'HEAD'],
credentials: true
}));
This is the cors i have added to the same node js file
app.use(session({secret: 'ssshhhhh',saveUninitialized: true,resave: true}));
This is the session middleware added to the same nodejs file
React:
$.ajax({
url:'http://192.168.0.144:9999/validate',
data:details,
type:"post",
success:function(data){ }
})
first ajax request sending process
React:
axios.post('http://192.168.0.144:9999/allusersdata').then((response) => {
userState(response.data.allUsers);
});
second axios request to send request.
Please someone help me with this issue. I am trying this for several days and many browsing searches still didnt find any.
Thanks in advance,
Regards,
A nodejs and react Noob.

Parse XML body from HTTP Push request with Express & Node.js, using body-parser-xml

I need to process a HTTP push request using Node.js express.
The request is sending the body in XML format, that's why I chose the body-parser-xml package for parsing.
My problem is, that the body isn't properly parsed – I guess because the package doesn't recognize the mime type of the transferred body.
The endpoint:
const express = require('express');
const bodyParser = require('body-parser');
require('body-parser-xml')(bodyParser);
const app = express();
const PORT = 8085;
app.use(express.urlencoded({ extended: true }));
app.use(bodyParser.xml({
limit:'25MB'
}));
app.post('/feed', function (req, res, body) {
console.log(req.headers);
console.log(req.body);
res.status(200).end();
});
The output:
{
host: 'localhost:8085',
accept: '*/*',
'x-meta-feed-type': '1',
'x-meta-feed-parameters': 'feed params',
'x-meta-default-filename': 'filename.xml',
'x-meta-mime-type': 'text/xml',
'content-length': '63'
encoding: 'UTF-8',
connection: 'Keep-Alive'
}
{
'<data id': '"1234"><name>Test</name><title>Test1234</title></data>'
}
I'm not able to change the request itself (it's external), only the Node.js endpoint.
Any idea how to process the content properly?
Thanks for your help!
The request has apparently been parsed by the
app.use(express.urlencoded({ extended: true }));
middleware, which means that it must have had Content-Type: application/x-www-form-urlencoded. Remove the two app.use lines, because they make "global" body-parsing decisions (for every request), whereas you need a special treatment only for one type of request.
If you instantiate the XML body parser with the "non-standard" (that is, wrong) type, it will parse the content as XML:
app.post('/feed',
bodyParser.xml({type: "application/x-www-form-urlencoded"}),
function (req, res) {
console.log(req.headers);
console.log(req.body);
res.status(200).end();
});

express.js CSURF cookie and header match, returning 403

I have a simple express server setup like:
app.use(bodyParser.json());
app.use(cookieParser());
app.use(csurf({ cookie: true }));
// routes
app.use(Routes imported from another file);
The client is currently just a simple form in react. I am loading some initial data before the react app loads and the csrf cookie is being set there.
I have a simple function for parsing the csrf cookie client side. I'm proxying the express server in create-react-app so I can't just set a meta tag in the header.
const csrfToken = () => {
const cookies = decodeURIComponent(document.cookie).split(';');
const token = cookies.find(cookie => cookie.includes('_csrf'));
if (token) {
return token.split('=')[1]
}
}
I am using fetch to send along data and the token
const response = await fetch(url, {
credentials: 'include',
method: 'POST',
headers: {
'Connection': 'keep-alive',
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken()
},
body: JSON.stringify({ ...body })
});
I've tried commenting out the line that tells the app to use csurf and checking that everything is present on the request. I can verify that the cookie and the header are matching in every request I send. Everything seems correct, but I am still getting a 403 error so I must be missing something. I'm at a lost to what it could be and all I could find googling is other people setting up their apps very similarly.
You are reading the content of the _csrf cookie and sending it back inside X-CSRF-Token header. This will not work.
The csurf middleware running inside Express has been configured by this code: app.use(csurf({ cookie: true })); to generate the _csrf cookie and send it to the client. The middleware expects you to:
Generate the second piece of CSRF data on the server.
Attach the second piece of data to the response sent to a client. As a result, the response arrives to the client with both the _csrf cookie and the second piece of data attached.
Ensure the incoming request from the client has the same _csrf cookie and the second piece of data copied into one of the six predefined places/locations (such as 'X-CSRF-Token' header or another location).
See this answer for more details.

Nodejs) Body of post request seems strange

I want to send a x-www-form-urlencoded request for the server. I give a json value for it like {username: 'asd', password: '12345'}.
Angular:
...
let headers: HttpHeaders = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
this._http.post('/api/authentication', form.value, {headers: headers, observe: 'response'}).subscribe((response:HttpResponse<Object>) => {
console.log(response); // response body {'{"username":"asd","password":"12345"}' : ""}
});
...
So I get something strange from back-end and I don't really understand what to change in my implementation to make this work like the input he got.
Nodejs (express):
//server.js
...
const bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true}));
...
--
//api/.../authentication.js
...
router.post('/', (req, res) => {
let post = req.body;
console.log( req.body); //same strange hash: {'{"username":"asd","password":"12345"}' : ""}
res.status(201).json(req.body);
});
...
Http header application/x-www-form-urlencoded means sending a x-www-form-urlencoded request to the server, that's correct.
However, bodyParser.json
only parse request type application/json(default value).
Returns middleware that only parses json and only looks at requests where the Content-Type header matches the type option. Type defaults to application/json.
So it is not correct.
You should send application/json request.
Or you should parse it as application/x-www-form-urlencoded, then decode the content (json).

Receive empty object in node js express request

I have a problem when i upload image from react native to node js server, this is my code
Client
var url = "http://192.168.55.120:3000/uploadimg";
var file = this.state.imgsrc.uri;
const data = new FormData();
data.append('token', 'testName');
data.append('photo', {
uri: file,
type: 'image/jpeg',
name: 'testPhotoName'
});
fetch(url, {
method: 'post',
headers: {
'Accept': 'application/json, application/xml, text/plain, text/html, *.*',
'Content-Type': 'multipart/form-data'
},
body: data
}).then(res => {
console.log(res)
});
and my server code
const express = require('express'),
bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.post('/uploadimg', function (req, res) {
console.log(req.body); // =====> empty object
})
My code is wrong ?
As you can check in body-parser docs, this package doesn't handle multipart form data bodies.
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
Also, you shouldn't need to specify the content type header in fetch; it'll handle it for you depending on the provided body.
You cannot stringify the formData as mentioned in their docs
Using the FormData API is the simplest and fastest, but has the disadvantage that data collected can not be stringified.
If you want to stringify a submitted data, use the pure-AJAX method.
You may consider trying it with util-inspect

Resources