I am using Socket.IO in my application. The React client uses socket.io-client 4.1.3, and the Node.js server uses socket.io 4.1.3
In the development environment on my local machine, everything works fine.
The React app runs on http://localhost:3000, and connects to the server using:
import io from 'socket.io-client';
const socket = io('http://localhost:5000/');
The Node.js server is configured as below:
const express = require('express');
const app = express();
const server = require('http').createServer(app);
const cors = require('cors');
const io = require('socket.io')(server, {
cors: {
origin: 'http://localhost:3000'
},
maxHttpBufferSize: '1e6'
});
app.set('io', io);
app.use(express.static('public'));
app.use(express.json({ limit: '7mb' }));
app.use(cors({ origin: 'http://localhost:3000' }));
server.listen(5000, () => console.log('Server started'));
In production, I am using Firebase to host the React app, in a subdirectory (e.g. https://www.example.com/app/).
In production, http://localhost:5000/ and http://localhost:3000 in the code above have also been changed to https://app.example.com and https://www.example.com/app respectively.
My server uses Ubuntu 20.04, Nginx, and Let’s Encrypt, with a server block set up as follows:
server {
server_name app.example.com;
location / {
proxy_pass http://localhost:5000/;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}server {
if ($host = app.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name app.example.com;
return 404; # managed by Certbot
}
In Google Chrome, I was getting No ‘Access-Control-Allow-Origin’ header is present on the requested resource as an error. Changing the origin from https://www.example.com/app to * in the Node.js code fixed this.
However, now I am getting the following error in my browser:
POST https://app.example.com/socket.io/?EIO=4&transport=polling&t=NirW_WK&sid=PmhwTyHRXOV4jWOdAAAF 400 (Bad Request)
Why would this be?
Thanks
3
Answers
A few small changes to both the Node.js and Nginx should resolve your problem:
Node.js
First off, I’d recommend that you change this:
to this (as specified here):
Nginx
Change this:
to this:
This post here can help give more information on CORS headers needed in Nginx reverse proxies
Try adding a variable port to access an environment variable. PORT should be set to https://app.example.com/
And use it everywhere that local host 3000 was used in your backend code.
This should also help
}
})
I was facing same issue and backend was on aws elasticbeanstalk, so we set Load Balancer, to handle multiple request calls and this error was fixed. So i think you need to check cloud base function for load balancing.