簡體   English   中英

Socket.io 給出 CORS 錯誤,即使我在服務器上允許 cors

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

我的節點服務器和客戶端在不同的端口(分別為 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”header 中使用通配符“*”。 因此不允許訪問 Origin 'null'。

注意:我在服務器上使用 express 並且我已經通過以下方式使用 cors 中間件:

app.use(cors());

其中app和cors分別是express和cors的實例。

如果按如下方式運行 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 的服務器對象與我正在偵聽的服務器對象不同。

接受的答案已過時

根據官方文檔,您可以將其添加到現有的 http 服務器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"],
}

早在 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參數支持該函數

請注意,在將 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);

希望能幫助到你。

如果您在 Chrome、Safari 和其他瀏覽器上運行 socket.io 應用程序,但在 Firefox 中仍然遇到 CORS 問題,並且您使用的是自簽名證書,那么問題在於 Firefox 默認不接受自簽名證書,並且您必須通過轉到 Firefox 的首選項 > 證書 > 查看證書 > 添加例外來添加例外。

如果您不這樣做,那么 Firefox 會顯示您發布的具有誤導性的錯誤,但在其開發人員工具的深處,您會發現此錯誤:MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT。 這表明 Firefox 根本不接受該證書,因為它是自簽名的。

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

以下代碼有幫助:

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

根據文檔(如果您使用的是 JS,則可以忽略打字稿的內容):

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

這在 python-Flask-SocketIO 中對我有用

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

對我來說,症狀是 CORS(沒有 Access-Control-Allow-Origin 標頭),在花了數小時嘗試這里的所有內容后,我意識到遠程網絡服務器未配置為正確處理 https://serverurl/socket.io。 在為“/socket.io”添加 nginx 位置處理程序后,錯誤消失了。

安裝 socket.io 版本 2 解決了我的問題

npm install socket.io@2

如果您使用 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();
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM