socket.io:io.origins 不是函数

Posted

技术标签:

【中文标题】socket.io:io.origins 不是函数【英文标题】:socket.io: io.origins is not a function 【发布时间】:2021-02-19 16:36:35 【问题描述】:

我正在尝试为我的 socket.io nodejs 服务器启用跨域同域请求,但由于某种原因它一直告诉我 io.origins 不是函数

var io = require('socket.io', 3000);
io.origins("*");

TypeError: io.origins 不是函数

**更新,跨域错误:**

跨域请求被阻止:同源策略不允许读取位于 http://:3000/socket.io/?EIO=3&transport=polling&t=NMWwT1R 的远程资源。 (原因:CORS 请求未成功)。

【问题讨论】:

【参考方案1】:

编辑 2: 至于为什么会出现 CORS 错误,是因为您没有正确配置 Socket.IO cors 选项。

现在,Socket.IO 的 cors 配置实际上被传递到 NPM 包 cors,因此您需要使您的 cors 配置与 cors 包一起使用。

对于你的情况,这看起来像:

cors: 
    // The `*` is used as the wildcard here.
    origin: "*",
    // Set the other options according to your needs.
    // The docs are here:
    // https://www.npmjs.com/package/cors#configuration-options
    methods: ["GET", "POST"],
    allowedHeaders: ["content-type"]

编辑 1: 既然我知道您使用的是 Socket.IO 3.0,我也许可以更好地帮助您。

Socket.IO 3.0 包含一系列重大更改(请参阅完整的更改日志here),这可能就是您收到TypeError: io.origins is not a function 的原因。

对于那个 CORS 错误,Socket.IO 3.0 删除了一些旧选项,并添加了一些新选项用于 CORS 管理。删除的选项之一是 origins 属性。这就是您的代码不起作用的原因:您实际上并没有设置任何 CORS 配置。要在 Socket.IO 3.0 中设置 CORS 配置,请使用以下选项:

// I still use a port here, because it works, but you could use @Aryas'
// code if you wish.
const io = socketIO(3000, 
  // Now, the CORS config.
  // You could either use the new `cors` property...
  cors: 
    origin: "https://example.com",
    methods: ["GET", "POST"],
    allowedHeaders: ["content-type"]
  ,
  // ...Or the old `allowRequest` function.
  allowRequest: function(req, callback) 
    callback(null, req.headers.referer.startsWith("https://example.com"));
  
);

哦,而且,不需要在 Express 中设置 CORS 选项; Socket.IO 在调用任何 Express 处理程序之前自动接收针对它的请求。

原始答案: 它告诉您,因为您的 io 变量不是 Socket.IO 服务器的实例。相反,它是 Socket.IO 服务器构造函数。为什么?

嗯,你有这个代码:

// You are passing two parameters to `require`: "socket.io", and 3000
var io = require("socket.io", 3000);

require 返回模块导出的任何内容,在这种情况下,它是 Socket.IO 服务器构造函数(不是它的实例)。你传递给require3000 没有任何作用,因为require 只接受一个参数。

为了获得一个Socket.IO服务器实例,你需要这样做:

// The clearer way:
// `socketIO` is the Socket.IO server constructor.
var socketIO = require("socket.io");
// `io` is the Socket.IO server instance.
var io = socketIO(3000);

// The shorter way:
// Calling the result of `require` (the Socket.IO server constructor) as a function.
var io = require("socket.io")(3000);

【讨论】:

它仍然说同样的事情: var socketIO = require("socket.io"); var io = socketIO(3000); io.origins("*"); TypeError: io.origins 不是函数 我也试过:io.set("origins", "*") 同样的事情:io.set 不是函数 等一下...您使用的是哪个版本的 Socket.IO? 我使用的是 3.0.0 版 好的,所以...我认为 Socket.IO 文档目前有点落后,但我会看看我能做些什么。【参考方案2】:

更新 2

正如您在此 https://pastebin.com/1TDhWxaC 代码中提到的,我发现您正在使用 fire fox 在 Chrome 或其他浏览器上尝试此代码,我认为它可以在该浏览器上运行

Firefox 中存在错误或问题证书或其他内容,您会在以下所有情况下注意到这一点

我建议你通过下面的问题和答案

    Firefox 'Cross-Origin Request Blocked' despite headers CORS request did not succeed on Firefox but works on Chrome Socket.io + Node.js Cross-Origin Request Blocked CORS Blocked with node.js and socket.io Socket.IO: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource

//火狐客户端出错: //跨域请求被阻止:同源策略不允许读取位于 http://:3000/socket.io/?EIO=3&//transport=polling&t=NMX8aWc 的远程资源。 (原因:CORS 请求没有成功)

更新 1 在您的 app.js 或 index.js 中 把代码放在下面

app.use(function (req, res, next) 
  res.header("Access-Control-Allow-Origin", '*');
  res.header("Access-Control-Allow-Credentials", true);
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
  res.header("Access-Control-Allow-Headers", 'Origin,X-Requested-With,Content-Type,Accept,content-type,application/json');
  res.header("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0");
  next();
);

如果您使用的是 firefox,请参阅此答案:*** 上的答案

如果你还没有在你的应用中使用过,请安装cors

你可以在 express 中使用 cors npm。

npm install cors

更新 app.js

var express = require('express')
var cors = require('cors')
var app = express()

app.use(cors())

原始答案 试试这个也许它可以为你工作它在我的应用程序中运行良好

var express = require('express');
var app = express();
var http = require('http').Server(app);
const io = require('socket.io')(http, 
  origins: '*:*'
);

http.listen(port);
console.log('Server is running on port:' + port);

【讨论】:

好吧,我不再收到该错误,但我在客户端收到了跨域请求被阻止错误:( 添加到主帖 看来我使用的是 3.0.0 我知道,但我说如果您使用的是整个问题中提到的 firefox 也许 3.0.0 只是被窃听了。我在 Chrome 上收到此错误:无法加载资源:net::ERR_CONNECTION_TIMED_OUT 如果我降级到 2.3.0 也是一样,所有这些答案都表明您需要访问服务器的 IP 地址并手动允许证书,但是当我尝试在浏览器中访问 socket.io 服务器的 IP 地址(和端口),它从不加载页面。什么都没有发生。

以上是关于socket.io:io.origins 不是函数的主要内容,如果未能解决你的问题,请参考以下文章

Socket.io-client - TypeError: socket_io_client_1.default 不是函数

Socket.io 未能发出函数

部署时socket.io服务器是不是需要与后端分开?

io() 函数前端——socket.io

Socket.io 随机聊天室

socket.io |异步响应是不是按顺序堆叠?