Httprequest not receiving response from express router - node.js

I am trying to initiate a XMLHttprequest and hoping to receive response from express routes which are being placed in my app.js file but it is not working. Can anybody help what is going wrong
Below are my code in two diff files
File 1
function signup_data_validation() {
const data = {
fname: 'Nasir',
lname: 'Khatri'
};
const xhr = new XMLHttpRequest();
const url = '../app.js/customers';
const string_data = JSON.stringify(data);
xhr.responseType = 'json';
xhr.onreadystatechange = () => {
if(xhr.readyState === XMLHttpRequest.DONE) {
console.log(this.responseType);
}
}
xhr.open('POST', url);
xhr.send(string_data);
}
signup_data_validation();
File 2:
const express = require('express');
const sqlite3 = require('sqlite3');
const db = new sqlite3.Database('./miclothing');
const app = express();
app.use(express.static('public')); // web resources location
const PORT = process.env.PORT || 4001;
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
next();
});
app.post('/app.js/customers', (req, res, next) => {
const query = req.query;
query = JSON.parse(query);
console.log(query.name);
console.log()
res.send("Done");
})
app.listen(PORT, () => {
console.log(`Sever is listening at ${PORT}`);
});

In File 1 change const url = '../app.js/customers' to the URL of your server.
const url = 'http://localhost:4001/app.js/customers'
You may change the port if the server is not listening on 4001

You are trying to assign to a constant(query = JSON.parse(query);), this will throw a type error.
You're checking req.query instead of req.body.
Also in your ajax request you set the responseType to JSON insted of the content type header as you're sending JSON but not receiving it.

Related

Cors request did not succeed when im trying to run it on another pc

so im developing website using nodejs, and then deploying it to microsoft azure, and using Azure Database for mysql server to be exact, and importing my databse using mysql workbench, now the problem is in the CORS, everyhting going well i run it on chrome and firefox in the same pc works fine, but when i try to acces the website using another pc, i get the error says "Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:3000/data/price%20asc. (Reason: CORS request did not succeed)".
heres my nodejs code:
//use path module
const path = require("path");
//use express module
const express = require("express");
//use hbs view engine
// const hbs = require('hbs');
//use bodyParser middleware
const bodyParser = require("body-parser");
//use mysql database
const mysql = require("mysql");
const app = express();
const db = require("./database");
//cors
const cors = require("cors");
// app.use(cors());
// app.use(
// cors({
// origin: "*",
// })
// );
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();
});
//konfigurasi koneksi
const conn = mysql.createConnection({
// host: 'localhost',
// user: 'root',
// password: '',
// database: 'domdom'
host: "domdom.mysql.database.azure.com",
user: "domdom#domdom",
password: "Banana123",
database: "schema1",
port: 3306,
ssl: true,
});
//connect ke database
conn.connect((err) => {
if (err) throw err;
console.log("Mysql Connected...");
});
//set views file
app.set("views", path.join(__dirname, "/"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.json());
app.use(express.static(__dirname));
app.param("productname", function (request, response, next, product) {
// ... Perform database query and
// ... Store the user object from the database in the req object
request.product = product;
return next();
});
app.param("sort", function (request, response, next, price) {
// ... Perform database query and
// ... Store the user object from the database in the req object
request.price = price;
return next();
});
app.param("id", function (request, response, next, id) {
// ... Perform database query and
// ... Store the user object from the database in the req object
request.id = id;
ß;
return next();
});
//get all data
app.get("/data/:sort", (req, res) => {
let sql = "SELECT * FROM products Order By " + req.price;
let query = conn.query(sql, (err, results) => {
res.json(results);
});
});
//untuk search and sort
app.get("/data/:productname/:sort", function (req, res) {
let sql =
"SELECT * FROM products WHERE name like '%" +
req.product +
"%' Order By " +
req.price;
let query = conn.query(sql, (err, results) => {
res.json(results);
});
});
//untuk save data
app.post("/save/:id", (req, res) => {
let sql =
"INSERT INTO cart SELECT * from products WHERE id = '" + req.id + "'";
let query = conn.query(sql, (err, results) => {
if (err) throw err;
res.redirect("/");
});
});
//render interface
app.get("/", (req, res) => {
res.render("index");
});
//server listening
app.listen(3000, () => {
console.log("Server is running at port 3000");
});
as you can see in the code i have tried 3 ways trying to solve this problem, but nothing works, please help.
If you are using Azure app service to host your nodejs app,the most fastest way to config CORS on Azure Portal => app service => CORS :
I did some test on my side and this is my nodejs server code(as you can see, no config for CORS) :
const express = require('express')
const app = express()
const port = process.env.PORT || 8080
app.use(express.json())
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.post('/', (req, res) => {
var body = req.body;
res.send(`Hello ${body.name}!`)
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
Test HTTP request from an local static web page:
<!DOCTYPE html>
<html>
<body>
<h1>The XMLHttpRequest Object</h1>
<button type="button" onclick="loadDoc()">Request data</button>
<p id="demo"></p>
<script>
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML = this.responseText;
}
};
xhttp.open("POST", "https://nodeweb05.azurewebsites.net/", true);
xhttp.setRequestHeader("Content-type", "application/json");
var body = {"name":"testuser"};
xhttp.send(JSON.stringify(body));
}
</script>
</body>
</html>
You can try it yourself.
If you want to config CORS on code level, just try the config below:
const express = require('express')
const app = express()
var cors = require('cors')
app.use(cors())

Node js CORS failure

I have been trying to build a web application using NODE and React without Express router but I am getting a lot of issues with the CORS part since both node and react are running on different ports. I don't want to use express in this case since i want to use native http module provided by node, hence I am unable to use CORS middleware which is in the npm library.
I have tried every possible solution which would work for resolving the CORS issue but I am at a dead end now. I have shared my server side code below.
/*
* Main server file
*/
//Depenedencies
let https = require('https');
let url = require('url');
let fs = require('fs');
let handlers = require('./lib/handlers');
let stringDecoder = require('string_decoder').StringDecoder;
let decoder = new stringDecoder('utf-8');
//server object definition
let server = {};
//https certifications
server.certParams = {
'key': fs.readFileSync('../lib/Certificates/serverKey.key'),
'cert': fs.readFileSync('../lib/Certificates/serverCert.crt')
};
server.https = https.createServer(server.certParams, (req, res) => {
server.unifiedServer(req, res);
});
//main server
server.unifiedServer = (req, res) => {
//converting url to url object
let parsedUrl = url.parse("https://" + req.rawHeaders[1] + req.url, true);
//constructing required params for handlers
let method = req.method;
let route = parsedUrl.pathname;
let queryStringObject = parsedUrl.query;
let headers = req.headers;
//function specific params
let requestBodyString = "";
let chosenHandler;
let requestObject = {};
let responsePayload = {
'Payload': {},
'Status': ""
};
//streaming in the req body in case of post req
req.on("data", function(chunk) {
requestBodyString += chunk;
});
//this is called regardless of the method of the req
req.on("end", function() {
//this is specific to post req
requestBodyString += decoder.end();
requestBodyString = method == "POST" ? JSON.parse(requestBodyString) : {};
//the request object sent to the handlers
requestObject.method = method;
requestObject.reqBody = requestBodyString;
requestObject.queryObject = queryStringObject;
chosenHandler = server.handlers[route] ? server.handlers[route] : server.handlers.notFound;
let headers = {
"Access-Control-Allow-Origin" : "https://localhost:3000/",
"Access-Control-Allow-Methods" : "OPTIONS, POST, GET",
"Access-Control-Allow-Headers" : "Origin, Content-Type"
};
chosenHandler(requestObject)
.then((result) => {
//post handler call
responsePayload.Status = "SUCCESS";
responsePayload.Payload = result;
//send the data back
res.writeHead(200,headers);
res.write(JSON.stringify(responsePayload));
res.end();
}).catch((error) => {
//error handler
responsePayload.Status = "ERROR-->" + error;
//send the data back
res.writeHead(200,headers);
res.write(JSON.stringify(responsePayload));
res.end();
});
});
};
//router definition
server.handlers = {
'/login': handlers.login,
'/signup': handlers.signup,
'/checkUserName': handlers.checkUserName,
'/checkEmail': handlers.checkEmail,
'/notFound': handlers.notFound
};
//init function
server.init = () => {
//start the https server
//TODO--> Change this to handle changing port and env
server.https.listen(5000, function() {
console.log('The https server is listening on port 5000 in Development mode');
});
};
//export the module
module.exports = server;
I am making a post request to test the connection but I am getting this evertime:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://localhost:5000/login. (Reason: CORS request did not succeed).
Can anyone please tell me what am I doing wrong?
Set the "Access-Control-Allow-Origin" header in the response stream object.
Try with the below snippet -
server = http.createServer(function(req,res){
// Set CORS headers
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Request-Method', '*');
res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
res.setHeader('Access-Control-Allow-Headers', '*');
if ( req.method === 'OPTIONS' ) {
res.writeHead(200);
res.end();
return;
}
// ...
});
OR it that does not work, try using -
res.setHeader('Access-Control-Allow-Headers', req.header.origin);
Use this middle ware after let decoder = new stringDecoder('utf-8');
var express = require('express');
var app = express();
var allowCrossDomain = function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
res.header('Access-Control-Allow-Credentials', 'true');
// intercept OPTIONS method
if ('OPTIONS' == req.method) {
res.status(200).send();
} else {
next();
}
};
app.use(allowCrossDomain);
This is relevent for express framework.

Angular to Node + Express.js http.post() stalled: status 204 no content. Suspected CORS Preflight OPTIONS

I'm using client side ionic with server side node.js + express.js. Currently testing in my local computer.
I am able to do a POST request through postman, however I couldn't make it through ionic.
Research
I have spent almost 1 day to investigate this. But I couldn't find a way to solve this. More over, there is no error on the client nor the server side, thus it is difficult for me to investigate this.
From what I can see, I suspect the error comes from the PREFLIGHT OPTIONS settings. I should set it somewhere in my node + express.
I am using the cors plugin https://www.npmjs.com/package/cors and use the settings to allow PREFLIGHT OPTIONS, however it still does not work.
I looked at the chrome network inspection, this is what I have:
And this is what it looks in the console.
My Client-side Code (Ionic)
postAPI() {
return new Promise ((resolve,reject)=>{
this.http.post("http://localhost:8080/api/status/", {
"body" : "This is the body post"
}, httpOptions).subscribe((val) => {
console.log("POST call successful value returned in body", val);
resolve();
}, error => {
console.log("POST call in error", error);
reject();
}, () => {
console.log("The POST observable is now completed.");
})
})
}
My Server-side Code (Node + Express)
Here, I am using CORS OPTIONS settings to allow all OPTIONS requests.
I am setting it in server.js while the route itself is in status.js.
server.js
const express = require('express'); // call express
const app = express(); // define our app using express
var cors = require('cors'); // setup CORS so can be called by ionic local app
const port = process.env.PORT || 8080; // set our port
// ALLOW CORS
app.use(cors());
// SET CORS for PREFLIGHT OPTIONS
app.options('*', cors());
// Libraries
const bodyParser = require('body-parser');
const admin = require('firebase-admin');
const serviceAccount = require('./serviceAccountKey.json');
// Json
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
// Firebase Configs
//firebase admin sdk for Firestore
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://menuu-sm-dev.firebaseio.com"
});
var afs = admin.firestore();
var db = afs;
app.set("afs", afs);
var db = admin.firestore();
const settings = {timestampsInSnapshots: true};
db.settings(settings);
app.set("db", db);
// ROUTES
app.use('/api',require('./routers/api/api'));
app.use('/',require('./routers/home'));
// START
app.listen(port);
console.log('Server is served on port ' + port);
api.js
// SETUP
const express = require('express'),
router = express.Router();
const url = require("url");
const path = require("path");
///const sanitizer = require("sanitize")();
// ROUTES (/api/)
router.use('/user',require('./user'));
router.use('/status',require('./status'));
router.use('/timeline',require('./timeline'));
router.use('/photo',require('./photo'));
router.use('/like',require('./like'));
router.use('/comment',require('./comment'));
router.use('/checkin',require('./checkin'));
router.use('/promotion',require('./promotion'));
// OTHERS
module.exports = router;
status.js
// SETUP
const express = require('express'),
router = express.Router();
const url = require("url");
const path = require("path");
const Timeline = require("../../models/Timeline");
const Post = require("../../models/Post");
///const sanitizer = require("sanitize")();
// ROUTES
// ===============================================================
// /status/
var statusRoute = router.route('');
// Create
statusRoute.post((req, res) => {
let query = url.parse(req.url,true).query;
let userKey = query.userkey;
let statusKey = query.statuskey; // ga dipake
let reqBody = req.body;
let db = req.app.get('db');
// ! remember to do sanitizing here later on
if (typeof userKey != 'undefined'){
// Create New Status
let newStatusRef = db.collection('status/'+userKey+'/status').doc();
newStatusRef.set(reqBody);
// Fan-Out
let docId = newStatusRef.id; // get pushed id
//let docId = "1";
// Insert request body to models
var post = new Post();
var timeline = new Timeline();
Object.entries(reqBody).forEach( ([key, value]) => {
timeline.set(key,value);
post.set(key,value);
}
);
// Specify operations to be done
var batch = db.batch();
let newPostRef = db.collection('posts/'+userKey+'/posts').doc(docId);
batch.set(newPostRef, post.data);
console.log("b" + batch);
// Timeline & Commit
getFollowers(userKey, db)
.catch((error) => {
console.error("Error writing document: ", error)
})
.then((followers) => {
// ATTENTION!!
// if followers > 9, batch write supposedly wont work because max limit of batch write is 10
if (followers.length!=0){
followers.forEach((f) => {
let newTimelineRef = db.collection('timeline/'+String(f)+'/timeline').doc(docId);
console.log(typeof batch);
console.log("a" + batch);
batch.set(newTimelineRef, timeline.data);
});
}
// Commit changes
batch.commit()
.then(() => {
console.log("POST Request");
res.json({"Action":"CREATE","Status":"Successful", "User key":userKey, "Post Key": docId, "followers":followers});
})
.catch((error) => {
console.error("Error writing document: ", error)
})
});
}
});
Could you help me find the cause of this issue. Thanks!
Replace app.use('cors') with the below code:
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", '*');
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
);
if (req.method === 'OPTIONS') {
res.header('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, GET');
return res.status(200).json({});
}
next();
});

CORS issues even after using npm cors plugin in node server

I have created a simple server in node js to take the request from a react app.
But for the GET method there is no CORS error but whenever I do post, it gives me an error.
For the POST method to work, I have implemented in index.js file of the actions folder and it should hit the url from the server.js file.
index.js
import axios from 'axios';
export const GET_NAVBAR = "GET_NAVBAR";
export const LOGIN = "LOGIN";
export const BASE_API_URL = "http://localhost:3030";
export const GUEST_API_URL = "https://XXX.XXX.XXX.X:5443/wcs/resources/store/1";
export const getNavbar = () => {
return axios.get(BASE_API_URL + '/topCategory').then(res => {
return {
type: GET_NAVBAR,
payload: res.data.express.catalogGroupView
};
});
};
export const login = () => {
return axios.post(GUEST_API_URL + '/guestidentity', {}).then(res => {
console.log(res);
return {
type: LOGIN,
payload: {}
}
}).catch(e => {
console.log(e);
return {
type: LOGIN,
payload: {}
}
});
};
server.js
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const Client = require('node-rest-client').Client;//import it here
const app = express();
const helmet = require('helmet');
const morgan = require('morgan');
// enhance your app security with Helmet
app.use(helmet());
// use bodyParser to parse application/json content-type
app.use(bodyParser.json());
app.use(cors());
// log HTTP requests
app.use(morgan('combined'));
app.post('/guestidentity', (req, res) => {
var client = new Client();
// direct way
client.post("https://XXX.XXX.XXX.X:5443/wcs/resources/store/1/guestidentity", (data, response) => {
res.send({express: data});
});
});
const port = 3030;
app.listen(port, () => console.log(`Server running on port ${port}`));
I don't know where my code is getting wrong. Can anybody please help me to troubleshoot this issue. I would be grateful if someone could provide an insight or guide me a little. Thanks
For my part I used
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();
});
It will accept from any * sources, you might want to change that later
In your server.js , add the following middleware.
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://localhost:3030/');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
};
app.use(allowCrossDomain);

Angular 4 file upload with other post data giving empty object on server side (node js)

I am stuck with a problem from last 3 hours, I was trying to upload file and other post data to the server side, I am using angular for frontend part and node for server side.
This is my component.ts code
save(data) {
console.log(data);
const files: Array<File> = this.filesToUpload;
console.log(files);
for(let i = 0; i < files.length; i++){
this.formData.append("image[]", files[i], files[i]['name']);
}
//trying to send some dummy entry but no luck
this.formData.append('title','dasdasdas');
// console.log(this.formData.getAll('image'));
// console.log('form data variable : '+
this.formData.toString());
// console.log(this.formData.getAll('image[]'));
this.restApi.addRecipe(this.formData).subscribe(res =>
{
console.log(res);
});
This is my angular service code:
addRecipe(data){
console.log(this.baseUrl);
const headers = new Headers({});
let options = new RequestOptions({ headers });
return this.http.post(this.baseUrl+'addRecipe',data,options).map(res=>res.json());
}
This is my server.js code:
const express = require('express');
const mongoose = require('mongoose');
const admin = require('./routes/admin');
const path = require('path');
const app = express();
const config = require('./config/config');
const bodyParser = require('body-parser');
const cors = require('cors');
mongoose.Promise = global.Promise;
mongoose.connect(config.database, (err) => {
if (err) {
console.log(err);
} else {
console.log('connected')
}
})
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'client/dist')));
app.use(cors());
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'DELETE, PUT');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
//admin route
app.use('/admin', admin);
app.listen(3000, (err) => {
if (err) console.log("err");
console.log("port started");
})
This is the controller code where I have written the logic of inserting:
module.exports.addRecipe = (req, res) => {
const body = req.body
console.log(body);
return;
...
}
whenever I console.log(body), I am getting a empty object {}, from the angular side I have tried changing the content type but nothing seems to be working, I am new to node and angular and I searched a lot about this problem but no solution seems to be working.

Resources