skip to Main Content

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


  1. 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:

    cors: {
      origin: 'http://localhost:3000'
    },
    

    to this (as specified here):

    cors: {
      origin: 'http://localhost:3000',
      methods: ["GET", "POST"]
    },
    

    Nginx

    Change this:

    location / {
      proxy_pass http://localhost:5000/;
    }
    

    to this:

    location / {
      add_header 'Access-Control-Allow-Origin' '*';
      add_header 'Access-Control-Allow-Credentials' 'true';
      add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
      proxy_pass http://localhost:5000/;
    }
    

    This post here can help give more information on CORS headers needed in Nginx reverse proxies

    Login or Signup to reply.
  2. Try adding a variable port to access an environment variable. PORT should be set to https://app.example.com/

    const port = process.env.PORT || 3000
    

    And use it everywhere that local host 3000 was used in your backend code.

    This should also help

    const io = require("socket.io")(server, {
    cors: {
    
    origin: port,
    methods: ["GET", "POST"],
    allowedHeaders: ['Access-Control-Allow-Origin'],
    credentials: false
    

    }
    })

    Login or Signup to reply.
  3. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search