CORS denying connection to socket io - javascript

I'm trying to use socket io to send and receive data in realtime, but when I run server and open the client page which connects using socket.io-client, I'm getting an error
I installed cors and used it like I've done multiple times before and I tried setting the headers of my response to Allow access from different origin but nothing worked.
this is the error I'm getting:
Access to XMLHttpRequest at 'http://localhost:5000/socket.io/?EIO=4&transport=polling&t=ONQYon3' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
this is my server side code
require("dotenv").config();
const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const cors = require("cors");
const { Server } = require("socket.io");
const app = express();
const server = require("http").Server(app);
const io = new Server(server);
app.use(bodyParser.json());
app.use(
cors({
origin: "*",
})
);
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
});
io.on("connection", (socket) => {
console.log("a user connected");
});
const port = process.env.PORT || 5000;
const url = process.env.MONGO_URI;
const start = async () => {
try {
await connectDB(url);
server.listen(port, (req, res) => {
console.log(`Server is listening on port ${port}`);
});
} catch (error) {
console.log(error);
}
};
start();
and all I'm doing on the frontend is using socket.io-client library to connect to the server in a react application like this.
import io from "socket.io-client";
const socket = io("http://localhost:5000");
any help is appreciated

You need to pass cors options to the io Server constructor itself.
E.g. instead of
const io = new Server(server);
you need
const io = new Server(server, {
cors: {
origin: '*',
}
});

I was able to solve the problem. it was because the client and server were running on different ports and even with cors defined socket.io needs its own cors setting in it in order to work, I changed it to this and it worked.
const io = require("socket.io")(5000, {
cors: {
origin: "*",
},
});

Related

Address already in use with Socket.io in Express

I'm trying to use websockets in my app but I'm not able to get Socket.io to connect to my server. Whenever I run the code below, I get this error:
Error: listen EADDRINUSE: address already in use :::3000
I've tried looking up some solutions, and I found that there's no other processes running on this port, so the issue has to be within the project. What could I be doing wrong here?
const express = require("express");
const mongoose = require("mongoose");
const app = express();
const { createServer } = require("http");
const httpServer = createServer(app);
const socketIO = require("socket.io")(3000, { cors: { origin: "*" } });
socketIO.on("connection", (socket) => {
console.log("connected");
});
const port = 3000;
const startServer = () => {
httpServer.listen(port);
console.log(`Listening on port ${port} πŸš€`);
};
mongoose
.connect(uri)
.then(() => startServer())
.catch((err) => {
console.log(err);
});
If you don't supply socket.io with an http server, it will create one for you. So your code is actually creating two http servers, both trying to listen on the same port which fails with EADDRINUSE.
Instead, pass the httpServer as the first parameter to socket.io instead of a port number:
const socketIO = require("socket.io")(httpServer, { cors: { origin: "*" } });
It's happening because
const startServer = () => {
httpServer.listen(port);
console.log(`Listening on port ${port} πŸš€`);
};
here already the address 3000 in use ... so you shouldn't pass the port:3000 into socketIO, better pass the httpServer, like :
const socketIO = require("socket.io") (httpServer, cors: { origin: "*" } });
socketIO.on("connection", (socket) => {
console.log("connected");
});

Failed To Fetch From Server Using Node.js and Heroku

I am trying to deploy my React app onto Heroku however I'm running into some graphql errors. When I manually deploy the app, the server and client both start up successfully however upon performing any actions that require a database fetch, I get a failed to fetch error and a "Failed to load resource: net::ERR_CONNECTION_REFUSED" error. I think this is because the server is in the correct location (IP-wise) but this app was created to run locally so the client is expected to be on the localhost network, not the heroku url it has now. I have changed the ENV variables various different times to see what combination of addresses would work for the server and client however nothing changed. I will post my server side code and ENV variables below:
const { ApolloServer } = require('apollo-server-express');
const cors = require('cors');
const express = require('express');
const mongoose = require('mongoose');
const resolvers = require('./resolvers/root-resolver');
const { typeDefs } = require('./typedefs/root-def');
const serverOptions = require('./server-config');
require('dotenv').config();
const { MONGO_URI, BACKEND_PORT, CLIENT_LOCAL_ORIGIN, SERVER_LOCAL_DOMAIN } = process.env;
// create express server handling our middleware
const app = express();
// since we presume cors is enabled, this next step is not optional, so cors
// is enable here instead of in options
app.use(cors({ origin: CLIENT_LOCAL_ORIGIN, credentials: true }));
const corsPolicy = async(req, res, next) => {
/*
TODO for 316 students: res.set(), Access-Control-Allow-Origin and Access-Control-Allow-Credentials headers,
have them set these, inspect error messages, understand why they're needed
*/
res.set("Access-Control-Allow-Origin", req.headers.origin.toString());
res.set("Access-Control-Allow-Credentials", true);
next();
}
app.options('*', cors());
app.use(corsPolicy);
// middleware application is configured to happen in server-config.js
serverOptions(app);
const server = new ApolloServer({
typeDefs: typeDefs,
resolvers: resolvers,
context: ({req, res}) => ({ req, res })
});
// since the express server has cors configured, cors on the apollo server
// can be false; passing the same options as defined on the express instance
// works as well
server.applyMiddleware({ app , cors: false});
mongoose.connect(MONGO_URI, {useNewUrlParser: true , useUnifiedTopology: true})
.then(() => {
app.listen({ port: BACKEND_PORT }, CLIENT_LOCAL_ORIGIN, () => {
console.log(`Server ready at ${SERVER_LOCAL_DOMAIN}:${BACKEND_PORT}`);
})
})
.catch(error => {
console.log(error)
});
[ENV Variables][1]
[1]: https://i.stack.imgur.com/5nqmp.png

socket io client not connecting to server using ipv4 address

I'm having a problem with testing the connection when I use https://localhost:3000/ it connects successfully but I want to use socket Io client on a different device on android application to be precise I searched it up and turns out localhost wont work I have to connect using ipv4 address well I tried it but didnt work - like this http http://192.168.XX.XX:3000 for example so what is the problem why doesnt it connect please help
server code:
var cors = require("cors");
const express = require("express");
const app = express();
const port = process.env.PORT || 3000 ;
const server = app.listen(port, () => {
console.log(`started on ${port}`);
})
const io = require('socket.io')(server, {
cors: { origin: "*" }
});
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('message', (message) => {
console.log(message);
io.emit('message', `${socket.id.substr(0,2)} said ${message}` );
});
});
require("dotenv").config();
app.use(express.json());
app.use(cors());
//routes setup
const homeGetRoute = require("./routes/test.js");
app.use("/home", homeGetRoute);
app.use(cors());

Does anyone know how to solve CORS issues with React Express?

I am trying to make Postman work with React JS using express. I am following a Mern Stack Development tutorial in free code camp. I have Cors extension enabled in my browsers, both in Chrome and in Edge. I keep getting this message in localhost:5000 "Cannot get /" and get this message {"msg":"This is CORS-enabled for an allowed domain."} in localhost:5000/users/add. My code looks something like this:
This is my server.js
const express = require('express');
const cors = require('cors');
const mongoose = require('mongoose');
require('dotenv').config();
const app = express();
const port = process.env.PORT || 5000;
app.use(cors());
app.use(express.json());
const uri = process.env.ATLAS_URI;
mongoose.connect(uri,{useNewUrlParser: true, useCreateIndex:true, useUnifiedTopology:true});
const connection= mongoose.connection;
connection.once('open', () =>{
console.log("Mongodb database connection established successfully");
})
const exercisesRouter= require('./routes/exercises');
const usersRouter= require('./routes/users');
var allowlist = ['http://localhost:5000']
var corsOptionsDelegate = function (req, callback) {
var corsOptions;
if (allowlist.indexOf(req.header('Origin')) !== -1) {
corsOptions = { origin: true } // reflect (enable) the requested origin in the CORS response
} else {
corsOptions = { origin: false } // disable CORS for this request
}
callback(null, corsOptions) // callback expects two parameters: error and options
}
app.use('./exercises',exercisesRouter);
app.use('./users', usersRouter);
app.get('/users/add', cors(corsOptionsDelegate), function (req, res, next) {
res.json({msg: 'This is CORS-enabled for an allowed domain.'})
})
app.listen(port, ()=>{
console.log(`Server is running on port: ${port}`);
});
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})
cords don’t have anything to do with this
Can you tell me where is yow route for β€œ/β€œ something like this
app.get(β€œ/β€œ, (req,res)=>{
…..
});
Yes exactly. You don’t have it. If the route/endPoint is not declared how do use expect them browsers to show you some else
When browssers open yow link at localhost:5000
They make a get request to β€œ/β€œ. So express just tell’em
Can not get β€œ/β€œ
I do not

React/NodeJS won't speak via localhost in development

I'm working to setup a Node backend to feed data and communicate with ReactJS for my frontend. Ultimately I am developing new company software to replace our current Transportation System.
I utilize Amazon EC2 Ubuntu 16.04 - for my own reasons for my business - and I simply cannot get my ReactJS frontend with Socket.IO to communicate with my nodeJS backend with Socket.IO on http://localhost:4000/.
This is my App.js in my react frontend when it calls
import React, { Component } from 'react';
import logo from './logo.svg';
import ioClient from 'socket.io-client';
import './App.css';
var socket;
class App extends Component {
constructor() {
super();
this.state = {
endpoint: 'http://localhost:4000/'
};
socket = ioClient(this.state.endpoint);
}
This is my nodeJS index for the backend
const mysql = require('mysql');
const http = require('http');
const express = require('express');
const cors = require('cors');
const app = express();
const server = http.createServer(app);
const io = require('socket.io').listen(server);
app.use(cors());
app.get('/', (req, res) => {
res.send('Server running on port 4000')
});
const sqlCon = mysql.createConnection({
host: 'localhost',
user: 'admin-user',
password: 'admin-pass',
database: 'sample'
});
sqlCon.connect( (err) => {
if (err) throw err;
console.log('Connected!');
});
io.on('connection', (socket) => {
console.log('user connected');
});
server.listen(4000, "localhost", () => {
console.log('Node Server Running on 4000')
});
I can get it to communicate via my actual Public IP address, but not via localhost. I really don't want to expose my backend on my public IP address to communicate with it for all users. This has probably been asked before, but I honestly can't find a clear answer for it anywhere and I've been looking for 3 days now. Node has no problem executing, and like I said if I create the socket.io connection from the public IP, I can get it to communicate and as far as I can tell node has no problem running the rest of the script as it connects to mariaDB no problem.
This is the error I keep receiving in my Chrome console.
polling-xhr.js:271 GET http://localhost:4000/socket.io/?EIO=3&transport=polling&t=MvBS0bE net::ERR_CONNECTION_REFUSED
polling-xhr.js:271 GET http://localhost:4000/socket.io/?EIO=3&transport=polling&t=MvBS3H8 net::ERR_CONNECTION_REFUSED
I'm running React via npm start for the time being, so my localhost:3000 is being reverse proxied to nginx for my React frontend to be visible on my public EC2 IP via port 80.
Any help is appreciated!
It may be a cross origin request issue. Have you tried to enable CORS on your app. You can also use proxy in your react app package.json if you do not want to enable cors on your app.
In your react app package.json you can add
"proxy":"http://localhost:4000"
It's probably because the port you are using isn't available in the server-side when it's running.
Use the server-side port like this,
var port = process.env.PORT || 3000;
server.listen(port, "localhost", () => {
console.log('Node Server Running on 4000')
});
and on the client-side just connect to the app URL, like,
this.state = {
endpoint: '/'
};
socket = ioClient(this.state.endpoint);
Just clean up your server a bit. Take this guy run him from whatever terminal or ide you use to get your server going.
let startTime = Date.now();
const express = require('express');
const bodyParser = require('body-parser');
const compression = require('compression');
var cors = require('cors');
const app = express();
app.use(compression());
app.use(bodyParser.json({ limit: '32mb' }));
app.use(bodyParser.urlencoded({ limit: '32mb', extended: false }));
const http = require('http').Server(app);
const io = require('socket.io')(http);
app.use(cors({ origin: 'null' }));
const request = require('request');
const port = 4000;
let pm2InstanceNumber = parseInt(process.env.NODE_APP_INSTANCE) || 0;
http.listen(port + pm2InstanceNumber, err => {
if (err) {
console.error(err);
}
console.log('Listening http://localhost:%d in %s mode', port + pm2InstanceNumber);
console.log('Time to server start: ' + (Date.now() - startTime) / 1000.0 + ' seconds');
setTimeout(() => {
try {
process.send('ready');
} catch (e) {}
}, 2000);
app.get('/', (req, res) => {
res.send('Server running on port 4000')
});
});
or just run node filename.js to serve this guy up.

Categories

Resources