Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Socket.io + Node.js Cross-Origin Request Blocked

People also ask

How do I enable cross origins in node js?

Here is how you can allow a single domain access using CORS options: var corsOptions = { origin: 'http://localhost:8080', optionsSuccessStatus: 200 // For legacy browser support } app. use(cors(corsOptions)); If you configure the domain name in the origin - the server will allow CORS from the configured domain.

Why are cross-origin requests blocked?

If the CORS configuration isn't setup correctly, the browser console will present an error like "Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at $somesite" indicating that the request was blocked due to violating the CORS security rules.

How do I fix a blocked CORS policy?

Use a Chrome extension to add Access-Control-Allow-Origin header into every response. To find one of them, just head over to Chrome Webstore and type in "CORS", dozens will show up in the search result. Or you can install CORS Helper, CORS Unblock or dyna CORS right away.


Simple Server-Side Fix

❗ DO NOT USE "socketio" package... use "socket.io" instead. "socketio" is out of date. Some users seem to be using the wrong package.

❗ I do not condone setting origin to * as this opens up the ability for phishing sites to imitate the look and feel of your site and then have it work just the same. If you set the origin, you can avoid this.

socket.io v3

docs: https://socket.io/docs/v3/handling-cors/

cors options: https://www.npmjs.com/package/cors

const io = require('socket.io')(server, {
  cors: {
    origin: '*',
  }
});

socket.io < v3

const io = require('socket.io')(server, { origins: '*:*'});

or

io.set('origins', '*:*');

or

io.origins('*:*') // for latest version

* alone doesn't work which took me down rabbit holes.


I am using v2.1.0 and none of the above answers worked for me. This did though:

import express from "express";
import http from "http";

const app = express();
const server = http.createServer(app);

const sio = 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();
    }
});

sio.on("connection", () => {
    console.log("Connected!");
});

server.listen(3000);

You can try to set origins option on the server side to allow cross-origin requests:

io.set('origins', 'http://yourdomain.com:80');

Here http://yourdomain.com:80 is the origin you want to allow requests from.

You can read more about origins format here


For anyone looking here for new Socket.io (3.x) the migration documents are fairly helpful.

In particular this snippet:

const io = require("socket.io")(httpServer, {
  cors: {
    origin: "https://example.com",
    methods: ["GET", "POST"],
    allowedHeaders: ["my-custom-header"],
    credentials: true
  }
});

I tried above and nothing worked for me. Following code is from socket.io documentation and it worked.

io.origins((origin, callback) => {
  if (origin !== 'https://foo.example.com') {
      return callback('origin not allowed', false);
  }
  callback(null, true);
});

If you are getting io.set not a function or io.origins not a function, you can try such notation:

import express from 'express';
import { Server } from 'socket.io';
const app = express();
const server = app.listen(3000);
const io = new Server(server, { cors: { origin: '*' } });

I just wanted to say that after trying a bunch of things, what fixed my CORS problem was simply using an older version of socket.io (version 2.2.0). My package.json file now looks like this:

{
  "name": "current-project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "devStart": "nodemon server.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "socket.io": "^2.2.0"
  },
  "devDependencies": {
    "nodemon": "^1.19.0"
  }
}


If you execute npm install with this, you may find that the CORS problem goes away when trying to use socket.io. At least it worked for me.