【问题标题】:Socket.io gives CORS error even if I allowed cors it on server即使我在服务器上允许它,Socket.io 也会出现 CORS 错误
【发布时间】:2016-06-13 07:49:46
【问题描述】:

我的节点服务器和客户端运行在不同的端口上(分别为 3001,5347)。 在我使用过的客户端上,

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

在服务器上我一一尝试了所有的

    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');

但我收到以下错误:

XMLHttpRequest 无法加载 http://127.0.0.1:3001/socket.io/?EIO=3&transport=polling&t=1456799439856-4590。当凭证标志为真时,不能在“Access-Control-Allow-Origin”标头中使用通配符“*”。因此不允许访问 Origin 'null'。

注意:我在服务器上使用 express,并且我已经通过以下方式使用 cors 中间件:

app.use(cors());

其中 app 和 cors 分别是 express 和 cors 的实例。

【问题讨论】:

  • 你是怎么解决这个问题的?

标签: node.js socket.io cors


【解决方案1】:

如果运行 Express 如下:

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

所以要启动socket.io,我们可以这样做:

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

问题是因为以下代码:

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

传递给 socket.io 的服务器对象与我正在监听的服务器对象不同。

【讨论】:

  • 这只是在调试几个小时后救了我。
  • 你救了我!但是,这样添加的原因是什么?
  • 您能否显示更多代码以便我理解您的意思?谢谢你,先生。
  • Holly Molly 终于解决了。UPVOTED。
【解决方案2】:

接受的答案已过时

根据官方文档,您可以将其添加到现有的 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);

使用此选项对象启用 cors 似乎可以解决问题

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

【讨论】:

  • 这在 2020 年有效! (不像我发现的其他东西)
  • 这就像一个魅力应该是公认的答案。
  • 不。我也在2020年,这行不通。这也不是 3.x 的文档所说的,但它所说的 3.x 也不起作用。 Socket.io 很烂。
  • origins 参数在这里没有做任何事情。如果您将 cors 设置为 true,则表示您允许所有请求。您需要将 cors 设置为其中包含“origin”的对象作为字符串或接受的来源数组: cors: { origin: ['127.0.0.1:800'] } 文档:github.com/expressjs/cors#configuration-options
  • @Shamshirsaz.Navid 谢谢你的链接。我确实让这个工作。该错误具有误导性。问题是由于我没有为客户端 socket.io 指定要连接的正确端口,因为端口映射到容器中。当我简单地使用 http 模块时,它现在尊重 socket.io cors 设置。
【解决方案3】:

早在 2014 年,他们就在 origin 参数中增加了对方法的支持:

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

您可以通过外部调用、数据库或数组来验证域...

函数fn执行如下逻辑:

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

能够动态定义 CORS 标头 https://github.com/socketio/socket.io/issues/1772

在迁移到 socket.io v3.0+ 时,关于如何设置 CORS 的迁移发生了变化。 https://socket.io/docs/v3/migrating-from-2-x-to-3-0/index.html#Configuration

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

socket.io v3.0之后:

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

socket.io v3.0的origin参数支持该功能

【讨论】:

  • 这是一个了不起的解决方案
【解决方案4】:

根据文档(如果你使用 JS,你可以忽略打字稿的东西):

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

【讨论】:

    【解决方案5】:

    2021 年 8 月:

    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);
    
    

    【讨论】:

      【解决方案6】:

      请注意,您可以在将 app 传递给 require('http') 之前将 cors() 与 app 一起使用,然后将其传递给 socket.io。按照这个顺序。这也应该有效。

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

      希望对您有所帮助。

      【讨论】:

      • 我得到的 cors 没有定义。它来自哪里?
      • 添加const cors = require('cors');
      【解决方案7】:

      如果您的 socket.io 应用程序在 Chrome、Safari 和其他浏览器上运行,但您在 Firefox 中仍然遇到 CORS 问题,并且您使用的是自签名证书,那么问题是 Firefox 不接受自签名证书默认情况下,您必须通过转到 Firefox 的首选项 > 证书 > 查看证书 > 添加例外来添加例外。

      如果您不这样做,Firefox 会显示您发布的具有误导性的错误,但在其开发人员工具的深处,您会发现此错误:MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT。这表明 Firefox 根本不接受证书,因为它是自签名的。

      【讨论】:

        【解决方案8】:

        以下代码有帮助:

        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);
        

        【讨论】:

          【解决方案9】:

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

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

          【讨论】:

            【解决方案10】:

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

            npm install socket.io@2
            

            【讨论】:

              【解决方案11】:

              如果您使用的是 Express,那么在您的服务开始代码之前定义一个这样的中间件...

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2020-09-19
                • 2020-03-06
                • 2018-12-23
                • 2019-12-13
                • 2015-09-22
                • 2015-07-18
                • 2022-01-05
                相关资源
                最近更新 更多