简体   繁体   中英

Socket.io gives CORS error even if I allowed cors it on server

My node server and client are running on different ports(3001,5347 respectively). On client I had used,

var socket = io('http://127.0.0.1:3001');

On server I tried all of following one by one

    1) io.set('origins', '*:*');
    2) io.set('origins', 'http://127.0.0.1:5347');
    3) io.set('origins', '*');
    4) io.set('origins', '127.0.0.1:5347');

But I'm getting following error:

XMLHttpRequest cannot load http://127.0.0.1:3001/socket.io/?EIO=3&transport=polling&t=1456799439856-4590 . A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'null' is therefore not allowed access.

Note: I'm using express on server and I'm already using cors middleware in following way:

app.use(cors());

Where app and cors are instances of express and cors respectively.

If running Express as follows:

var app = express();
var server = app.listen(3000);

So to start socket.io, we can do the following:

var io = require('socket.io').listen(server);

The problem was because of following code:

var http = require('http').Server(app);
var io = require('socket.io')(http);

The server object passed to socket.io was not the same as the server object I'm listening on.

The accepted answer is outdated

According to the official docs, you can add it to an existing http Server https://socket.io/docs/server-initialization/#Attached-to-an-existing-HTTP-server

const server = require('http').createServer();
const options = { /* ... */ };
const io = require('socket.io')(server, options);
io.on('connection', socket => { /* ... */ });
server.listen(3000);

to enable cors using this options object seemed to do the trick

options={
 cors:true,
 origins:["http://127.0.0.1:5347"],
}

Back in 2014 they added support for method as part of the origin parameter:

let socket = io(web_server, {
    cors: { 
        origin: function(origin, fn) {
            if(origin == 'http://example.com')
                return fn(null, origin);
            return fn('Error Invalid domain');
        } 
    },
});

You can validate the domain with an external call, a database or an array...

The function fn execute the following logic:

function fn(err2, origin) {
    if (err2 || !origin) {
        next(err2);
    } else {
        corsOptions.origin = origin;
        cors(corsOptions, req, res, next);
    }
}

Ability to dynamically define CORS headers https://github.com/socketio/socket.io/issues/1772

While migrating to socket.io v3.0+ , there is a migration change on how to setup CORS. https://socket.io/docs/v3/migrating-from-2-x-to-3-0/index.html#Configuration

Before socket.io v3.0:

const io = require("socket.io")(httpServer, {
  origins: ["https://example.com"],

  // optional, useful for custom headers
  handlePreflightRequest: (req, res) => {
    res.writeHead(200, {
      "Access-Control-Allow-Origin": "https://example.com",
      "Access-Control-Allow-Methods": "GET,POST",
      "Access-Control-Allow-Headers": "my-custom-header",
      "Access-Control-Allow-Credentials": true
    });
    res.end();
  }
});

After socket.io v3.0:

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

The function is supported on the origin parameter in v3.0 of socket.io

Note that you can use cors() with app before you pass app into require('http'), which is then passed into socket.io. In this order. This should work too.

const app = express();

app.use(cors());
const http = require('http').Server(app);
const io = require('socket.io')(http);

Hope it helps.

If you get socket.io app working on Chrome, Safari and other browsers but you still encounter CORS issues in Firefox, and you are using a self-signed certificate, then the problem is that Firefox does not accept self-signed certificates by default, and you have to add an exception by going to Firefox's Preferences > Certificates > View Certificates > Add Exception.

If you don't do this, then Firefox shows the error you posted which is misleading, but deep within its Developer Tools, you will find this error: MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT. This indicates that Firefox is not accepting the certificate at all because it is self-signed.

AUG 2021:

const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const app = express();
const cors = require('cors');

app.use(
  cors({
    origin: ['https://americanairlines.com'],
    credentials: true,
    methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
    allowedHeaders: ['Origin', 'X-Requested-With', 'Content-Type', 'Accept'],
  })
);

const server = http.createServer(app);
const io = new Server(server, {
  cors: { origin: ['https://americanairlines.com'], credentials: true },
});

io.on('connection', async (socket) => {
  console.log('a user connected');
});

server.listen(5000);

Following code helped:

const PORT = process.env.PORT || 4000;
const app = express();
const server = app.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
});
const io = socket(server);

Acording with the doc (you can ignore the typescript stuff if you're using JS):

const io: Server = new Server(server, {
cors: {
    origin: "*",
    methods: ["GET", "POST"]
  },
});

这在 python-Flask-SocketIO 中对我有用

socketio =  SocketIO(app,cors_allowed_origins="*")

For me the symptom was CORS (No Access-Control-Allow-Origin header) and after spending hours trying everything here I realized that the remote webserver wasn't configured to handle https://serverurl/socket.io properly. After adding a nginx location handler for "/socket.io" the errors vanished.

安装 socket.io 版本 2 解决了我的问题

npm install socket.io@2

If you are using Express then define a middleware like this before your serve start code...

app.use(function(request, response, next) {
  response.header("Access-Control-Allow-Origin", "*");
  response.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM