Socket.io + Node.js跨源请求被阻止

Wal*_*mad 52 sockets node.js cors socket.io

我正在使用node和socket.io来编写聊天应用程序.它在Chrome上工作正常但mozilla在启用跨源请求时出错.

跨源请求已阻止:同源策略不允许在http://waleedahmad.kd.io:3000/socket.io/?EIO=2&transport=polling&t=1401964309289-2&sid=1OyDavRDf4WErI-VAAAI上读取远程资源.这可以通过将资源移动到同一域或启用CORS来解决.

这是启动节点服务器的代码.

var express = require('express'),
    app = express(), 
    server = require('http').createServer(app),
    io = require('socket.io').listen(server),
    path = require('path');
server.listen(3000);

app.get('/', function(req, res) {
    res.sendfile(__dirname + '/public/index.html');
});
Run Code Online (Sandbox Code Playgroud)

在客户端.

var socket = io.connect('//waleedahmad.kd.io:3000/');
Run Code Online (Sandbox Code Playgroud)

HTML页面上的脚本标记.

<script type="text/javascript" src="//waleedahmad.kd.io:3000/socket.io/socket.io.js"></script>
Run Code Online (Sandbox Code Playgroud)

我也在app根目录中使用.htaccess文件.(waleedahmad.kd.io/node).

Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
Run Code Online (Sandbox Code Playgroud)

Jas*_*ing 69

简单的服务器端修复

var io = require('socket.io')(server, { origins: '*:*'});
Run Code Online (Sandbox Code Playgroud)

要么

io.set('origins', '*:*');
Run Code Online (Sandbox Code Playgroud)

要么

io.origins('*:*') // for latest version
Run Code Online (Sandbox Code Playgroud)

* 独自不起作用,让我失去了兔子洞.

  • 从 v3.x 开始,请参阅此 ( https://socket.io/docs/v3/handling-cors/ ) 和此 ( https://github.com/expressjs/cors#configuration-options ) 链接。``` var io = require('socket.io')(http, { 'cors': { 'methods': ['GET', 'PATCH', 'POST', 'PUT'], 'origin': true // 接受任何域 } }); ```` (5认同)
  • socket.io v4.4.1 仅第一个选项添加 `cors: { origin : '*',}}` 解决了问题 (3认同)
  • 我正在使用最新版本,但不是,它给我连接被拒绝的错误 (2认同)

Ole*_*leg 31

您可以尝试origins在服务器端设置选项以允许跨源请求:

io.set('origins', 'http://yourdomain.com:80');
Run Code Online (Sandbox Code Playgroud)

http://yourdomain.com:80是您要允许来自的原点.

您可以在此处阅读有关origins格式的更多信


小智 24

对于在这里寻找新的 Socket.io (3.x) 的人来说,迁移文档非常有用。

特别是这个片段:

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


Kwa*_*rko 19

我正在使用v2.1.0,以上答案均不适合我。虽然这样做:

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);
Run Code Online (Sandbox Code Playgroud)


小智 11

客户:

const socket = io('https://sms-server.cedrick1227.repl.co/', { });
Run Code Online (Sandbox Code Playgroud)

服务器:

const io = new socket.Server(server, { cors: { origin: '*' } });
Run Code Online (Sandbox Code Playgroud)

它对我来说就像一种魅力。

  • 您能添加更多解释吗?你的代码有什么作用以及它如何帮助OP? (2认同)

KAR*_*N.A 9

In my case, I'm using an HTTP server and socket.io

Error:

var http = require('http').Server(app);
var io = require('socket.io')(http);
Run Code Online (Sandbox Code Playgroud)

Solution:

var http = require('http').Server(app);
var io = require('socket.io')(http,  { cors: { origin: '*' } });
Run Code Online (Sandbox Code Playgroud)


has*_*ghe 8

我在上面尝试过,对我没有任何帮助。以下代码来自socket.io文档,并且可以正常工作。

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


Ole*_*nko 7

如果你得到io.set not a functionio.origins not a function,你可以尝试这样的表示法:

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


小智 7

我只想说,在尝试了很多事情之后,解决我的 CORS 问题的方法只是使用旧版本的 socket.io(2.2.0 版)。我的 package.json 文件现在看起来像这样:

{
  "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"
  }
}


Run Code Online (Sandbox Code Playgroud)

如果您执行npm install此操作,您可能会发现在尝试使用 socket.io 时 CORS 问题消失了。至少它对我有用。


小智 5

我也一直在努力解决这个问题,直到我看到文档说:“您不能将 'withCredentials' 设置为 true with origin: *,您需要使用特定的 origin:”。所以我的代码看起来像这样,希望有用:

网络客户端

const { io } = require("socket.io-client");
const socket = io("localhost:3000", {
  extraHeaders: {
    "my-custom-header": "abcd"
  }
});
Run Code Online (Sandbox Code Playgroud)

服务器

var express = require('express');
const app = express();
const http = require('http');
const httpServer = http.createServer(app);
const io = require("socket.io")(httpServer, {
  cors: {
    origin: '*',
    methods: ["GET", "POST"],
  }
});
Run Code Online (Sandbox Code Playgroud)