Socket.io and node JS resulting CORS blocked issue - node.js

I've been working on chat functionality. There are two kinds of clients, One is the frontend of my application and the second is random another website.
I know there are plenty of issues like this but I tried all of the solution but I'm still getting following error:
Access to XMLHttpRequest at 'https://mydomain/socket.io/?EIO=3&transport=polling&t=NCjoM1w' from origin 'null' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
and this the error I'm getting on client-side of my own front end:
https://mydomain/socket.io/?EIO=3&transport=polling&t=NCjnJUX 404 (Not Found)
This is how I'm trying to connect from client-side.
var socket = io.connect("https://mydomain:443/", {secure: true, port: '443'});
and this is my server.js code
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const passport = require("passport");
const users = require("./routes/api/users");
const base = require("./routes/api/base");
const leads = require("./routes/api/leads");
const requests = require("./routes/api/requests");
const offApp = require("./routes/api/offApp");
const chat = require("./routes/api/chat");
const chatSocket = require("./routes/socket/chat");
const path = require("path"); // on top
const app = express();
// const client = require('socket.io').listen(4000).sockets;
const https = require('https');
const fs = require('fs');
var options = {
pfx: fs.readFileSync('certificate.pfx'),
passphrase: 'password'
};
app.all('/*', 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, *');
next();
});
var server = https.createServer(options, app);
var client = require("socket.io").listen(server);
client.origins('*:*') ;
server.listen(443);
// Bodyparser middleware
app.use(
bodyParser.urlencoded({
extended: false
})
);
app.use(bodyParser.json());
// DB Config
const db = require("./config/keys").mongoURI;
// Connect to MongoDB
mongoose
.connect(
db,
{ useNewUrlParser: true }, (err, db) => {
if (err) {
throw err;
}
console.log('MongoDB connected');
chatSocket(db, client);
});
// Passport middleware
app.use(passport.initialize());
// Passport config
require("./config/passport")(passport);
// Routes
app.use("/api/users", users);
app.use("/api/base", base);
app.use("/api/leads", leads);
app.use("/api/requests", requests);
app.use("/api/offapp", offApp);
app.use("/api/chat", chat);
const port = process.env.PORT || 5000;
app.use(express.static("client/build")); // change this if your dir structure is different
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});
app.listen(port, () => console.log(`Server up and running on port ${port} !`));
Please help me resolve this CORS and other issues. I am using the Azure app service. That's why I can't use any other port than 80 and 433

Install cors package using npm i cors
In your app.js file,
const cors = require('cors')
app.use(cors());

// use CORS like that-
// you need to use it as middle ware
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*"); // update to match the domain you will make the request from
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});

Danish try this solution, I hope it will work
const client = require("socket.io")(server, {
handlePreflightRequest: (req, res) => {
const headers = {
"Access-Control-Allow-Headers": "Content-Type, Authorization",
"Access-Control-Allow-Origin": req.headers.origin, //or the specific origin you want to give access to,
"Access-Control-Allow-Credentials": true
};
res.writeHead(200, headers);
res.end();
}
});
client.on("connection", () => {
console.log("Connected!");
});
server.listen(443);

Related

Node js_CORS block access

I'm trying to communicate with the front react at localhost:3000 and the backend side nodeJS is localhost:5000 but the problem I keep getting this message and I can't find a solution how to solve it
Access to XMLHttpRequest at 'http://localhost:5000/socket.io/?EIO=3&transport=polling&t=NSheHsx' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
GET-polling-xhr.js:268 GET http://localhost:5000/socket.io/?EIO=3&transport=polling&t=NShel1V net::ERR_FAILED
I tried every solution on the internet but without any chance
var corsOptions = {
origin: "https://localhost:3000/",
optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
};
app.use(cors(corsOptions));
this is the server.js
require("dotenv").config();
const express = require("express");
const morgan = require("morgan");
const cors = require("cors");
const loadRoutes = require("./routes/index");
const app = express();
var server = require("http").createServer(app);
var io = require("socket.io")(server);
const path = require("path");
let stream = require("./controllers/stream");
var corsOptions = {
origin: "https://localhost:3000/",
optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
};
app.use(cors(corsOptions));
app.use(express.json());
app.use(fileUpload());
// database config
require("./config/db");
//require config
require("dotenv").config({
path: "./config/config.env",
});
//config for only developement
if (process.env.NODE_ENV === "developement") {
app.use(
cors({
origin: process.env.CLIENT_URL,
})
);
}
app.use(morgan("dev"));
//load all routes
loadRoutes(app);
io.of("/stream").on("connection", stream);
//---------------------------------------------
app.use((req, res, next) => {
res.status(404).json({
success: false,
message: "Page Not found",
});
});
//start our web server and socket.io server listening
server.listen(process.env.PORT, function () {
console.log(`listening on ${process.env.PORT}`);
})
changes that I made based on answer below but same error
require("dotenv").config();
const express = require("express");
const morgan = require("morgan");
const cors = require("cors");
const loadRoutes = require("./routes/index");
const app = express();
var server = require("http").createServer(app);
var io = require("socket.io")(server);
const path = require("path");
let stream = require("./controllers/stream");
var corsOptions = {
origin: "http://localhost:3000/",
optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
};
// add this headers to your request and yow problems will be gone.
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.use(cors(corsOptions));
app.use(express.json());
app.use(fileUpload());
// database config
require("./config/db");
//require config
require("dotenv").config({
path: "./config/config.env",
});
//config for only developement
if (process.env.NODE_ENV === "developement") {
app.use(
cors({
origin: process.env.CLIENT_URL,
})
);
}
app.use(morgan("dev"));
//load all routes
//cors anwser2
app.option("*",cors())
loadRoutes(app);
io.of("/stream").on("connection", stream);
//---------------------------------------------
app.use((req, res, next) => {
res.status(404).json({
success: false,
message: "Page Not found",
});
});
//start our web server and socket.io server listening
server.listen(process.env.PORT, function () {
console.log(`listening on ${process.env.PORT}`);
})
Any idea on solving this error ?
have you already tried enabling PREFLIGH like described on 'cors' lib?
There is a section on the docs explaining about 'complex' requests that need to make a preflight request before making the actual request.
Here is a simple way to enable to test:
app.options('*', cors()) // include before declaring the route
I got this information from this section on the readme here: https://www.npmjs.com/package/cors#enabling-cors-pre-flight
Tho it's not recomended using wildcard '*' in production, so be careful :)
hope I helped
yow broh, you need to add them access-control headers
at yow code before your routes add it to express.
also I see you have
var corsOptions = {
origin: "https://localhost:3000/",
optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
};
your origin cannot be "https://localhost:3000/" in localhost change it to "http://localhost:3000/"
require("dotenv").config();
const express = require("express");
const morgan = require("morgan");
const cors = require("cors");
const loadRoutes = require("./routes/index");
const app = express();
var server = require("http").createServer(app);
var io = require("socket.io")(server);
const path = require("path");
let stream = require("./controllers/stream");
var corsOptions = {
origin: "https://localhost:3000/",
optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
};
// add this headers to your request and yow problems will be gone.
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.use(cors(corsOptions));
app.use(express.json());
app.use(fileUpload());
// database config
require("./config/db");
//require config
require("dotenv").config({
path: "./config/config.env",
});
//config for only developement
if (process.env.NODE_ENV === "developement") {
app.use(
cors({
origin: process.env.CLIENT_URL,
})
);
}
app.use(morgan("dev"));
//load all routes
loadRoutes(app);
io.of("/stream").on("connection", stream);
//---------------------------------------------
app.use((req, res, next) => {
res.status(404).json({
success: false,
message: "Page Not found",
});
});
//start our web server and socket.io server listening
server.listen(process.env.PORT, function () {
console.log(`listening on ${process.env.PORT}`);
})

Socket.io + nodejs = Error during WebSocket handshake: Unexpected response code: 500

I've been working on chat functionality for my website hosted on Azure app service. I'm using the socket on port 443 as app service won't allow any other port than 80 and 443.
Socket functionality works fine on localhost but this error shows up when I deploy:
websocket.js:122 WebSocket connection to 'wss://mydomain/socket.io/?EIO=3&transport=websocket' failed: Error during WebSocket handshake: Unexpected response code: 500
this is I'm connecting on client-side:
const socket = io.connect("https://mydomain:443", {transports: ['websocket'], secure: true, port: '443'});
This is my server.js file
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const passport = require("passport");
const users = require("./routes/api/users");
const base = require("./routes/api/base");
const leads = require("./routes/api/leads");
const requests = require("./routes/api/requests");
const offApp = require("./routes/api/offApp");
const chat = require("./routes/api/chat");
const chatSocket = require("./routes/socket/chat");
const path = require("path"); // on top
const app = express();
const cors = require('cors')
const https = require('https');
const fs = require('fs');
/**
* App.
*/
const privateKey = fs.readFileSync('private.key').toString();
const certificate = fs.readFileSync('certificate.crt').toString();
const ca = fs.readFileSync('ca_bundle.crt').toString();
const server = https.createServer({key:privateKey,cert:certificate,ca:ca }, app);
const client = require('socket.io').listen(server);
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*"); // update to match the domain you will make the request from
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
client.origins('*:*');
client.set('transports', ['websocket']);
server.listen(443);
// Bodyparser middleware
app.use(
bodyParser.urlencoded({
extended: false
})
);
app.use(bodyParser.json());
// DB Config
const db = require("./config/keys").mongoURI;
// Connect to MongoDB
mongoose
.connect(
db,
{ useNewUrlParser: true }, (err, db) => {
if (err) {
throw err;
}
console.log('MongoDB connected');
chatSocket(db, client);
});
// Passport middleware
app.use(passport.initialize());
// Passport config
require("./config/passport")(passport);
// Routes
app.use("/api/users", users);
app.use("/api/base", base);
app.use("/api/leads", leads);
app.use("/api/requests", requests);
app.use("/api/offapp", offApp);
app.use("/api/chat", chat);
const port = process.env.PORT || 5000;
app.use(express.static("client/build")); // change this if your dir structure is different
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});
app.listen(port, () => console.log(`Server up and running on port ${port} !`));
I haven't found any error in logs
I was able to solve this problem by using the default port. (Not the best solution but for Azure App service I couldn't find any other solution)
For the client-side I am connecting to socket like this.
const socket = io.connect("https://example.com", {transports: ['websocket'], secure: true});
And this is how my server-side looks like.
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const passport = require("passport");
const users = require("./routes/api/users");
const base = require("./routes/api/base");
const leads = require("./routes/api/leads");
const requests = require("./routes/api/requests");
const offApp = require("./routes/api/offApp");
const chat = require("./routes/api/chat");
const chatSocket = require("./routes/socket/chat");
const path = require("path"); // on top
const app = express();
const cors = require('cors')
const https = require('https');
const fs = require('fs');
/**
* App.
*/
var privateKey = fs.readFileSync('private.key').toString();
var certificate = fs.readFileSync('certificate.crt').toString();
var ca = fs.readFileSync('ca_bundle.crt').toString();
// var server = https.createServer({key:privateKey,cert:certificate,ca:ca }, app);
var server = require('http').createServer(app);
var client = require('socket.io').listen(server);
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*"); // update to match the domain you will make the request from
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
client.origins('*:*');
client.set('transports', ['websocket']);
// Bodyparser middleware
app.use(
bodyParser.urlencoded({
extended: false
})
);
app.use(bodyParser.json());
// DB Config
const db = require("./config/keys").mongoURI;
// Connect to MongoDB
mongoose
.connect(
db,
{ useNewUrlParser: true }, (err, db) => {
if (err) {
throw err;
}
console.log('MongoDB connected');
chatSocket(db, client);
});
// Passport middleware
app.use(passport.initialize());
// Passport config
require("./config/passport")(passport);
// Routes
app.use("/api/users", users);
app.use("/api/base", base);
app.use("/api/leads", leads);
app.use("/api/requests", requests);
app.use("/api/offapp", offApp);
app.use("/api/chat", chat);
const port = process.env.PORT || 5000;
app.use(express.static("client/build"));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});
server.listen(port);

Request body empty with Node PUT from Angular 7

I've been banging my head against the wall on this one for a few hours. I'm not sure why it doesn't work but it's probably something simple I'm missing. It usually is...
Anyway, I'm doing a simple HTTP PUT from Angular 7 like this:
protected put(cmd: string, body: any) {
let headers = new HttpHeaders();
headers.append('Content-Type','application/json');
console.log(body);
return this._http.put(cmd, body, {headers: headers});
}
cmd and body are being passed in. I can see the body print out in the console and the cmd path is correct to hit my route path in Node.
From there, it comes into my Node/Express app. Which goes as follows:
'use strict';
const express = require('express');
const bodyParser = require('body-parser')
// Constants
const PORT = 8080;
const HOST = '0.0.0.0';
// App
const app = express();
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
app.use(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", "Origin, X-Requested-With, Content-
Type, Accept");
next();
});
app.use('/api', require('./routes/routes'));
app.use('/api/add-user', require('./routes/add-user/routes'));
app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);
And this is my routes file that console prints the empty body:
const express = require('express');
const router = express.Router();
const dvAdmin = require('../../controller/controller');
//Routes
//GETS
//PUTS
router.put('/addCCUser', function (req, res) {
console.log(req.body);
});
module.exports = router;

node.js express routes are not working in remote server

I am creating a REST api using Node.js And Express, The application works fine including routes and other functanalities on local computer but when uploaded to windows server routes are not working properly, I was able to see Hello World printed on my from home page e.g:- www.abcd.com/,
But when routes are being used eg:- www.abcd.com/users/ it gives 404 - File or directory not found.
Here is my code
server.js
const http = require('http')
const app = require('./app')
const server = http.createServer(app);
server.listen(process.env.PORT, () => {
console.log("Server Started");
});
app.js
const express = require('express');
const morgan = require('morgan');
const bodyParser = require('body-parser');
const app = express();
app.use(morgan('dev'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
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();
});
const users_routes = require('./api/routes/users.routes');
const message_routes = require('./api/routes/message.routes');
const group_routes = require('./api/routes/group.routes');
const key_routes = require('./api/routes/key.routes');
console.log(users_routes.toString());
app.use('users', users_routes);
app.use('message', message_routes);
app.use('group', group_routes);
app.use('key', key_routes);
app.use('/', (req, res, next) => {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<H1>Hello World!</H1>');
});
module.exports = app;
user.routes.js
const express = require('express');
const router = express.Router();
router.get('/', (req, res, next) => {
Console.log("Hello there");
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<H1>Hello World!</H1>');
});
module.exports = router;
Log file after starting app
Server Started
It prints function when used typeof(user_routes)

ExpressJS post route is not working and returning an error

I am working on a Mean stack application, I have defined an expressjs backend post route to store some data on server, but its not working and returning an error message which is provided for handling errors 'An error occurred in form api'.
router.post('/userform', function (req, res, next) {
var form = new Form({
controlType: req.body.controlType,
label: req.body.label,
required:req.body.required ,
placeholder: req.body.placeholder,
options: req.body.options
});
form.save(function(err, result) {
if (err) {
return res.status(500).json({
title: 'An error occurred in form api',
error: err
});
}
res.status(201).json({
message: 'Form created',
obj: result
});
});
});
Its the mongoose schema that I am using:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var mongooseUniqueValidator = require('mongoose-unique-validator');
var formSchema = new Schema({
controlType: {type: String, required: true},
label: {type: String, required: true},
required: {type: Boolean},
placeholder: {type: String},
options: [String], //to store options for select or radio input
} , {collection: 'inputForm'});
formSchema.plugin(mongooseUniqueValidator);
module.exports = mongoose.model('Form', formSchema);
It is the app.js file:
// Get dependencies
const express = require('express');
const path = require('path');
const http = require('http');
const bodyParser = require('body-parser');
var mongoose = require('mongoose');
// Get our API routes
const api = require('./routes/api');
const formApi = require('./routes/form');
const app = express();
mongoose.connect('localhost:27017/test-mean');
// Parsers for POST data
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// Point static path to dist
app.use(express.static(path.join(__dirname, 'dist')));
//to avoid cross origin requests errors
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
res.setHeader('Access-Control-Allow-Methods', 'POST, GET, PATCH, DELETE, OPTIONS');
next();
});
// Set our api routes
app.use('/api', api);
app.use('/form', formApi);
// Catch all other routes and return the index file
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'));
});
/**
* Get port from environment and store in Express.
*/
const port = process.env.PORT || '3000';
app.set('port', port);
/**
* Create HTTP server.
*/
const server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port, () => console.log(`API running on localhost:${port}`));
Please help. Thanks
Add your body-parser code above all router
// Get dependencies
const express = require('express');
const path = require('path');
const http = require('http');
const bodyParser = require('body-parser');
var mongoose = require('mongoose');
// Parsers for POST data
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// Get our API routes
const api = require('./routes/api');
const formApi = require('./routes/form');
const app = express();
mongoose.connect('localhost:27017/test-mean');
// Point static path to dist
app.use(express.static(path.join(__dirname, 'dist')));
//to avoid cross origin requests errors
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
res.setHeader('Access-Control-Allow-Methods', 'POST, GET, PATCH, DELETE, OPTIONS');
next();
});
// Set our api routes
app.use('/api', api);
app.use('/form', formApi);
// Catch all other routes and return the index file
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'));
});
/**
* Get port from environment and store in Express.
*/
const port = process.env.PORT || '3000';
app.set('port', port);
/**
* Create HTTP server.
*/
const server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port, () => console.log(`API running on localhost:${port}`));

Resources