Cors policy in socketio express [duplicate] - node.js

This question already has answers here:
socket.io, 'Access-Control-Allow-Origin' error
(9 answers)
Closed 1 year ago.
I am getting following error:
Access to XMLHttpRequest at 'http://localhost:8001/socket.io/?EIO=3&transport=polling&t=NWrnTy1' from origin 'http://localhost' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
my node server code:
//import express from "express";
//import http from "http";
const app = require("express")();
const server = require("http").createServer(app);
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
const io = require("socket.io")(server);
io.on("connection", () => {
console.log("Connected!");
});
var redis = require('redis');
var url = "redis://localhost:6379"
var client = redis.createClient(url);
client.on('message', function(channel, msg) {
io.sockets.emit(msg);
});
client.subscribe('JoinCall');
server.listen(8001);
my index.html on apache:
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script>
//var socket = io();
var socket = io.connect('http://localhost:8001');
sock.on('twits', function(msg) {
console.log('message received: '+msg);//Do something with message here.
});
</script>

I had ton of problems with CORS and they were all resolved by installing the npm package cors and let it do this job. I would suggest to remove your manual setting headers and try this instead. Saved my life.
Install the cors package by running 'npm i cors'. Then in your server file add these:
const cors = require('cors');
// Add these lines above any route / mounting
app.use(cors());
app.options('*', cors());

in socket.io client I used a neutral transport layer:
var socket = io('http://localhost:8001', { transports : ['websocket'] });

Related

How to solve cors error in socket.io laravel and nodejs signalling app

i have a chat app built with laravel and socket.io. My laravel app is located on one domain while my nodejs app is on another domain. Connecting to my nodejs signalling app gives a cors error while the nodejs app also returns cors error. Here is my nodejs app
"use strict";
require('dotenv').config();
const express = require('express');
const app = express();
const fs = require('fs');
const options = {
key: fs.readFileSync(process.env.KEY_PATH),
cert: fs.readFileSync(process.env.CERT_PATH)
};
const https = require('https').Server(options, app);
const io = require('socket.io')(https);
io.origins('*:*');
const listner = https.listen(process.env.PORT, function() {
console.log('Listening on ', listner.address().port);
});
//allow only the specified domain to connect
io.set('origins', process.env.DOMAIN + ':*');
require('./socket')(io);
app.get('/', function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
// Add this
if (req.method === 'OPTIONS') {
res.header('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, OPTIONS');
res.header('Access-Control-Max-Age', 120);
return res.status(200).json({});
}
res.send('Ok');
next();
I have installed a cors middleware on my laravel backend but no difference whatsover. Any help will be appreciated
You need to remove these two line. cos, you have first set for any origin and the you have specified domain with env.
io.origins('*:*');
io.set('origins', process.env.DOMAIN + ':*');
Exact way to allow user is
// process.env.DOMAIN == "https://anydomain.com:port"
// process.env.DOMAIN != "anydomain.com:port"
const options={
cors:true,
origins:[process.env.DOMAIN],
}
const io = require('socket.io')(https, options);

How to solve CORS error in nodejs while using Postman?

I created a REST Api using nodejs and mongodb and i wanted to test it in postman but while doing so I am getting a CORS error.
var express = require('express');
var log = require('morgan')('dev');
var bodyParser = require('body-parser');
var properties = require('./config/properties');
var db = require('./config/database.js');
//hero routes
var herosRoutes = require('./api/heros/heros.routes');
var app = express();
//configure bodyparser
var bodyParserJSON = bodyParser.json();
var bodyParserURLEncoded = bodyParser.urlencoded({extended:true});
//initialise express router
var router = express.Router();
// call the database connectivity function
db.mongoc();
// configure app.use()
app.use(log);
app.use(bodyParserJSON);
app.use(bodyParserURLEncoded);
// Error handling
app.use(function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Credentials", "true");
res.setHeader("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
res.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Origin,Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers,Authorization");
next();
});
// use express router
app.use('/api',router);
//call heros routing
herosRoutes.hero(router);
// intialise server
app.listen(properties.PORT, (req, res) => {
console.log(`Server is running on ${properties.PORT} port.`);
})
Whenever i make any create or get request, i get this CORS error in postman. How to solve this?
CORS Error: The request has been blocked because of the CORS policy
Have you tried the CORS package from Express? It's a simple setup:
npm i cors
Then just use it in your app (this enables ALL CORS requests):
app.use(cors());
Docs
Also answered here.
if someone is still having this issue, Postman doesn't provide an origin when calling the API, so when we have restricted CORS policy an error is generated saying Error: Not allowed by CORS.
Sample code for bypassing this issue is this:
const whitelist = ['https://localhost:3001']
const corsOptions = {
origin: function (origin, callback) {
if(!origin){//for bypassing postman req with no origin
return callback(null, true);
}
if (whitelist.indexOf(origin) !== -1) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'))
}
}
}
app.use(cors(corsOptions));

Socket.io and node JS resulting CORS blocked issue

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);

CORS error not showing when using express [duplicate]

This question already has answers here:
How does the 'Access-Control-Allow-Origin' header work?
(19 answers)
Closed 2 years ago.
When I create two servers using Nodejs with http and both have express as request handler, one is running at localhost:3000, which is used for handling api. And the other at localhost:5000 and I try to fetch the api from localhost:3000, I expect to get a cors error, but surprisingly I can fetch it with no error. I wonder why, is it because of express?
The localhost:5000 code
const express = require('express');
const app = express();
const axios = require('axios');
const http = require('http');
const server = http.createServer(app);
app.get('/', async (req, res) => {
try {
const response = await axios.get('http://localhost:3000/users');
console.log(typeof response.data);
res.send(response.data[1]);
} catch(err) {
console.error(err);
}
});
server.listen(5000);
try putting cors rules,
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
res.setHeader('Access-Control-Allow-Methods', 'GET,HEAD,PUT,PATCH,POST,DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});

React axios calls to Express API in Heroku deployment

I have a React todo app I built using create-react-app and I built a simple express server to query mongoDB to get all the appointment objects. It works just as expected when I am running it on my machine. The front end spins up on localhost:3000 and the server on localhost:3001. I use axios to make a get request to localhost:3000/api/appointments to load all the appointments into the App.js state. I uploaded it to Heroku and I got a CORS error on the request. After that, I tried to just use the route 'api/appointments' in the request and every permutation of that I can come up with which all respond with 404 errors.
Where does the node.env variable spin up the server on Heroku? And how do I call it fromm a React app with axios?
Same question in a different context if it helps:
When I run the app on my machine and access it with Postman, I can GET localhost:3001/api/appointmentsand it returns an array of JSON objects from the database just as I would expect. When I deploy to Heroku GET https://appointment-ledger-map.herokuapp.com/api/appointments returns all the markup for index.html. I assume this means that the api server is up and running because it responds but why is it not responding with the array of JSON objects as expected?
// server.js
var express = require('express');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var Appointment = require('./model/appointments');
//and create our instances
var app = express();
var router = express.Router();
//set our port to either a predetermined port number if you have set
//it up, or 3001
var nodeEnv = process.env.NODE_ENV || 'development';
var port = process.env.PORT || 3001;
var host = process.env.HOST || '0.0.0.0';
//db config
mongoose.connect('mongodb://josh11:josh11#ds133162.mlab.com:33162/heroku_tl016m5d');
//now we should configure the API to use bodyParser and look for
//JSON data in the request body
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
//To prevent errors from Cross Origin Resource Sharing, we will set
//our headers to allow CORS with middleware like so:
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.setHeader('Access-Control-Allow-Methods', 'GET,HEAD,OPTIONS,POST,PUT,DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers');
//and remove cacheing so we get the most recent appointments
res.setHeader('Cache-Control', 'no-cache');
next();
});
//now we can set the route path & initialize the API
router.get('/', function(req, res) {
res.send({ message: 'API Initialized!'});
console.log('Api initialized');
});
//Use our router configuration when we call /api
app.use('/api', router);
//starts the server and listens for requests
app.listen(port, host, function() {
console.log(`api running on port ${port}`);
});
//adding the /appointments route to our /api router
router.route('/api/appointments')
//retrieve all appointments from the database
.get(function(req, res) {
//looks at our Appointment Schema
Appointment.find(function(err, appointments) {
if (err)
res.send(err);
//responds with a json object of our database appointments.
res.send(appointments)
});
console.log(appointments);
})
//post new appointment to the database
.post(function(req, res) {
var appointment = new Appointment();
//body parser lets us use the req.body
appointment.appointmentTitle = req.body.appointmentTitle;
appointment.appointmentDate = req.body.appointmentDate;
appointment.appointmentTime = req.body.appointmentTime;
appointment.appointmentDescription = req.body.appointmentDescription;
appointment.appointmentDestination = req.body.appointmentDestination;
appointment.appointmentOrigin = req.body.appointmentOrigin;
appointment.travelMode = req.body.travelMode;
appointment.save(function(err) {
if (err)
res.send(err);
res.send({ message: 'Appointment successfully added!' });
});
});
// App.js
loadAppointments() {
axios.get('/api/appointments')
.then(res => {
this.setState({
appointments: res.data,
filteredAppointments: res.data
});
})
}
npm install cors --save
then
var cors = require('cors');
finally
mongoose.connect('mongodb://josh11:josh11#ds133162.mlab.com:33162/heroku_tl016m5d');
//now we should configure the API to use bodyParser and look for
//JSON data in the request body
app.use(cors()); **//Must be before BodyParser**
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
//To prevent errors from Cross Origin Resource Sharing, we will set
//our headers to allow CORS with middleware like so:
Re-deploy it and voila :)
Hope it helped you

Resources