Socket.IO 尝试通过 https:// 而不是 wss:// 进行连接并收到 CORS 错误

Lit*_*ore 3 javascript websocket cors socket.io

我正在从JavaScript's原始WebSocketAPI切换到Socket.IO有关cryptocurrency价格的实时数据。在使用常规时,WebSocket我没有问题连接Kraken和获取我需要的数据。但是,在尝试与 连接时Socket.IO,出现CORS错误。

CORS 政策已阻止在“ https://ws.kraken.com/socket.io/?EIO=3&transport=polling&t=Mxg8_5_ ”处访问 XMLHttpRequest :不存在“Access-Control-Allow-Origin”标头在请求的资源上。

在 Chrome 开发工具网络选项卡中,我收到Invalid request来自Kraken. 我假设Socket.IO在尝试建立websocket连接时尝试发送某种预检请求,但由于Kraken's CORShttp 请求的策略而失败。有没有办法完全绕过这种XMLHttpRequest尝试并立即尝试websocket连接,因为常规WebSocketAPI 在建立此连接时没有问题并且似乎没有发送预检请求?这是香草和Socket.IO插座:

// vanilla websocket
const vanillaWS = new WebSocket('wss://ws.kraken.com');
vanillaWS.onopen = () => {
  console.log('vanilla websocket opened');
}
vanillaWS.onmessage = (message) => {
  console.log(message.data);
}

// socket.io websocket
const ioSocket = io('wss://ws.kraken.com');
ioSocket.on('connect', () => {
  console.log('socket.io socket opened');
});
ioSocket.on('message', (message) => {
  console.log(message.data);
});
Run Code Online (Sandbox Code Playgroud)

如您所见,这些在功能上应该非常相似,但是虽然第一个按预期工作,但第二个却抛出了错误。

And*_*bie 5

文档

Socket.IO 不是什么

Socket.IO 不是 WebSocket 实现。尽管 Socket.IO 确实在可能的情况下使用 WebSocket 作为传输,但它为每个数据包添加了一些元数据:数据包类型、命名空间和需要消息确认时的数据包 ID。这就是为什么 WebSocket 客户端将无法成功连接到 Socket.IO 服务器,而Socket.IO 客户端也无法连接到 WebSocket 服务器的原因。请在此处查看协议规范 。

因此,如果您尝试使用的端点没有运行 Socket.IO 服务器,这将不起作用。

也就是说,如果是,您可以使用以下transports参数强制使用 websockets :

const ioSocket = io(endpoint, {
  transports: ['websocket']  // forces websockets only
});
Run Code Online (Sandbox Code Playgroud)

底线:Socket.IO 不是 WebSockets 连接的替代品。Socket.IO 使用 WebSockets 来实现其目标:“Socket.IO 是一个能够在浏览器和服务器之间进行实时、双向和基于事件的通信的库”