Node.js Express.js not always sending valid json - json

Here is the express code
app.post('/v1/sessions' function(req,res){
res.send({id:1234});
});
For some reason the json response comes back like this
OK{ id: 1234}
Why is the OK there?
EDIT
Ok so here is all of my code. I don't see where it would be sending the OK.
var express = require('express');
var app = express();
app.enable('trust proxy');
app.use(express.bodyParser());
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
app.post('/v1/sessions', function(req, res) {
if(req.body.email == 'testuser#captusr.com' && req.body.password == 'testpass'){
res.send(200, JSON.stringify({token:{id:'longstring',email:'testuser#captusr.com'}}));
} else {
res.send({code:403, error:"Invalid email or password"});
}
});
app.all('*', function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'HEAD, GET, POST, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, X-Requested-With, Origin, Accept');
res.header('Access-Control-Allow-Credentials', 'true');
if (req.method.toLowerCase() === 'options') {
res.send(200);
} else {
next();
}
});
app.listen(3000);
console.log('Listening on port 3000');

Can you replace this line:
res.send(200, JSON.stringify({token:{id:'longstring',email:'testuser#captusr.com'}}));
with this and see if that solves it. Express does the 200 and JSON.stringify for you, so don't re-do it.
res.send({token:{id:'longstring',email:'testuser#captusr.com'}});

Related

How do I use express.json() and set headers (res.setHeader) simultaneously?

I am trying to view the body of a POST request and also set some headers. Specifically, I need to allow localhost -> localhost communication, which means adding Access-Control-Allow-Origin: * as a header.
My code so far is:
const express = require("express");
const app = express();
const port = 8080;
app.use(express.json());
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
res.sendStatus(200);
next();
});
app.post('/', function (req, res) {
console.log(req.body.name)
res.end();
});
app.listen(port, () => console.log(`Listening on port ${port}`));
When I run the server I get Cannot set headers after they are sent to the client.
How can I combine both app.use()s?
I've tried changing the order of the calls but that doesn't work.
I figured out a way after I posted the question, so I'm sharing it here for anyone else:
const express = require("express");
const app = express();
const port = 8080;
app.use(function( req, res, next ) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Content-Type"
);
res.sendStatus(200);
let data = "";
req.on("data", function( chunk ) {
data += chunk;
console.log(data);
next();
});
});
app.listen(port, () => console.log(`Listening on port ${port}`));

Create Web server using Node js model MVC

I'm trying to create a web server, and I'm using to MVC model so I tried to use routes inside so I don't know how can I do this. in the console log thats return all data otherwise in postman I test it it doesn't works. here is my code.
AirModel.js :
AirMonitoring.getAllData = (result) =>{
db.query('SELECT * FROM AirMonitoring', (err, res)=>{
if(err){
console.log('Error while fetching airMonitoring', err);
result(null,err);
}else{
console.log('AirMonitoring fetched successfully');
result(null,res);
}
})
}
airController.js :
exports.getAllData = (req, res)=> {
AirModel.getAllData((err, airMonitoring) =>{
if(err)
res.send(err);
console.log('data', airMonitoring);
res.send(airMonitoring)
})
}
index.js :
const server = http.createServer(function(req, res) {
console.log("http was created!");
if(req.url == '/airMonitoring'){
res.writeHead(200, { 'Content-Type': 'application/json' });
// get latest record of airMonitoring
router.get('/airMonitoring', airController.getAllData);
res.end();
}
});
It's not very clear what router is but I'm assuming it's an express router, and that's not how routing works. Currently you are (re?)defining the route on each request. The routing page is a good place to start, but basically you need to define the routes once.
var express = require('express')
var app = express()
app.get('/airMonitoring', airController.getAllData);
app.listen(PORT, () => {
console.log(`Example app listening at http://localhost:${PORT}`)
})
And also in your AirModel.js you have an error as far as I can tell, when handling the database error you should provide it as first argument, not second:
result(null,err); /* has to be result(err, null) */

Insert data into res.body back to client

with my client js i have perform a fetch and send along some data.
And i've attempted to do a res.send or res.json to send a result back.
Do I need to create a new json and send it?
Express Server
const express = require('express');
const app = express();
const pg = require('pg');
const conString = 'postgres://postgres:password#localhost/postgres';
const bodyParser = require('body-parser');
app.use(bodyParser.json()); //support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true})); //support encoded bodies
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
app.listen(3000, function () {
console.log('Server listening on port 3000!');
});
app.post('/', function(req, res){
var uname = req.body.username;
var pw = req.body.password;
QueryByUserName(uname, function(err, result){
if(err){
console.error('error happened', err);
//handle error
}
if(uname == result.username){
//name is in our database
if(pw == result.password){
console.log("User and Password Correct!");
res.json({ message: 'correct' });
} else {
console.log("Password Incorrect!");
res.json({ message: "incorrect" });
}
} else if(result.username == "undefined"){ //placeholder
console.log("username does not exist");
res.send( {message: "dne"} );
console.log(res);
}
});
});
function QueryByUserName(input, callback) {
pg.connect(conString, function(err, client, done){
if(err){
callback(err);
return;
}
client.query(SelectAll(), function(err, result){
//Query database for all usernames
done();
var isFound = false;
for(var x = 0; x < result.rows.length; x++){
//loop through all usernames from database.
if(result.rows[x].username == input){
isFound = true;
//username exists, now we obtain the rest of the data.
client.query(findDataInDatabase(input, '*'), function(err, result){
done();
if(err){
callback(err);
return;
}
console.log(result.rows[0]);
callback(null, result.rows[0]);
//return all information regarding user to callback function
});
} else if(x == (result.rows.length - 1) && !isFound){
callback(null, {username: "undefined"}); //placeholder
//Username does not exist in database
}
} //end of For Loop
});
});
}
function findDataInDatabase(username, WhatWeLookingFor) {
return 'select ' + WhatWeLookingFor + ' from users where username = \'' + username + '\'';
}
Express server side will try to send a message to the client.
but when I do this i did a console.log(res) it shows that the body is { null, null, null}
Client login Function
handleLogin: function(){
let fetchData = {
method: "post",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: this.state.user,
password: this.state.password,
message: null
})
}
var fromServer = fetch('http://localhost:3000/', fetchData)
.then(function(response){
if( !response.ok){
throw Error (response.statusText);
}
console.log(response);
console.log(response.message);
console.log(response.body);
console.log(response.body.text);
return response.json();
})
.catch(error => console.log("there was an error --> " + error));
},
Edit : Screenshots below
Since you have returned, res.json({ message: 'correct' });
use,
response.message
Instead of,
response.body
var fromServer = fetch('http://localhost:3000/', fetchData)
.then(response => response.json())
.then(response => {
console.log(response.message);
})
After talking to Sraven, who was a huge help.
The code is sending a req, and the server is responding with a response with the message included. The problem was on the client side where it was not getting the response correctly.
Below is the working code and was able to finally produce a response.
var fromServer = fetch('http://localhost:3000/', fetchData)
.then(response => response.json())
.then(response => {
console.log(response.message);
})

How to use fetch to post with content-type of application/json

I have a react application that does a fetch call to an API as follows:
postForm(state) {
var formData = state.formData;
return fetch('http://localhost:3000/api/V0.1/formSubmit', {method: 'POST', headers: {"Content-Type": "application/json"}, body: JSON.stringify(formData)})
.then((response) => response.json())
.then((responseJson) => {
console.log(responseJson);
return null;
})
.catch((error) => {
console.error(error);
});
}
however, it gets blocked by CORS as the spec states that application/json is non-standard content type.
However, I'm not sure how I can modify my fetch call to perform the required pre-flight request to get it to allow application/json.
The API call is:
app.post("/api/v0.1/formSubmit", function(req, res) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8080');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', '*');
var formData=req.body;
console.log(formData);
res.status(200).json(formData);
});
Before defining your routing. declare
app.use(function(req, res, next) {
var oneof = false;
if(req.headers.origin) {
res.header('Access-Control-Allow-Origin', req.headers.origin);
oneof = true;
}
if(req.headers['access-control-request-method']) {
res.header('Access-Control-Allow-Methods', req.headers['access-control-request-method']);
oneof = true;
}
if(req.headers['access-control-request-headers']) {
res.header('Access-Control-Allow-Headers', req.headers['access-control-request-headers']);
oneof = true;
}
if(oneof) {
res.header('Access-Control-Max-Age', 60 * 60 * 24 * 365);
}
// intercept OPTIONS method
if (oneof && req.method == 'OPTIONS') {
res.send(200);
}
else {
next();
}
});
In CORS, the request is checked for available methods on server. i.e. in OPTIONS request. When you get the successful response, you will able to send request.
You can enable CORS for specific pages also. study here https://github.com/expressjs/cors

Parsing JSON in Express without BodyParser

I'm trying to write a simple express server that takes incoming JSON (POST), parses the JSON and assigns to the request body. The catch is I cannot use bodyparser. Below is my server with a simple middleware function being passed to app.use
Problem: whenever I send dummy POST requests to my server with superagent (npm package that lets you send JSON via terminal) my server times out. I wrote an HTTP server in a similar fashion using req.on('data')...so I'm stumped. Any advice?
const express = require('express');
const app = express();
function jsonParser(req, res, next) {
res.writeHead(200, {'Content-Type:':'application/json'});
req.on('data', (data, err) => {
if (err) res.status(404).send({error: "invalid json"});
req.body = JSON.parse(data);
});
next();
};
app.use(jsonParser);
app.post('/', (req, res) => {
console.log('post request logging message...');
});
app.listen(3000, () => console.log('Server running on port 3000'));
I think the problem like to get rawBody in express.
Just like this:
app.use(function(req, res, next){
var data = "";
req.on('data', function(chunk){ data += chunk})
req.on('end', function(){
req.rawBody = data;
req.jsonBody = JSON.parse(data);
next();
})
})
And you need catch the error when parse the string to json and need to judge the Content-type of the Req.
Good luck.
another way that worked with me by collecting all chunks into an array and parsing the concatenated chunks.
app.use("/", (req, res, next)=>{
const body = [];
req.on("data", (chunk) => {
console.log(chunk);
body.push(chunk);
});
req.on("end", () => {
const parsedBody = Buffer.concat(body).toString();
const message = parsedBody.split('=')[1];
console.log(parsedBody);
console.log(message);
});
console.log(body);
});
To get access to req.body this worked for me:
app.use(express.json({extended: false}));
In Express v4.16.0 onwards:
app.use(express.json())