使用 Socket.IO 反应和烧瓶 - CORS 问题

Posted

技术标签:

【中文标题】使用 Socket.IO 反应和烧瓶 - CORS 问题【英文标题】:React and Flask with Socket.IO - CORS problem 【发布时间】:2021-08-05 16:12:19 【问题描述】:

我正在尝试创建一个与 React 客户端(端口 3000)有 socket.io 连接的 Flask 服务器(端口 5000)。当我尝试执行服务器脚本(如下所示)时,即使我使用的是 CORS,我也会收到一条错误消息“http://localhost:3000 is not an accepted origin”。

服务器测试.py:

from flask import Flask
from flask_socketio import SocketIO, emit
from flask_cors import CORS, cross_origin

import os
from dotenv import load_dotenv, find_dotenv
load_dotenv(find_dotenv())

app = Flask(__name__)
app.config['CORS_HEADERS'] = 'Content-Type'
app.config['SECRET_KEY'] = os.environ.get('SECRET')
socketio = SocketIO(app)
CORS(app)

@socketio.on('connect')
@cross_origin()
def handle_connection():
  emit('server-client', 'Test message')


@socketio.on('client-server')
@cross_origin()
def handle_client_msg(msg):
  print("\n" + str(msg))


if __name__ == '__main__':
  app.run(host="localhost", port=os.environ.get('PORT'))
  socketio.run(app)

App.jsx:

import  io  from 'socket.io-client';

// ...

useEffect(() => 
  const socket = io('http://localhost:5000');

  socket.on('server-client', msg => 
    alert(msg);
    socket.emit('client-server', 'Client: Message received!');
  );
, []);

WSL 终端中的错误消息:

 * Serving Flask app 'server-test' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://localhost:5000/ (Press CTRL+C to quit)
http://localhost:3000 is not an accepted origin. (further occurrences of this error will be logged with level INFO)
127.0.0.1 - - [16/May/2021 00:27:31] "GET /socket.io/?EIO=4&transport=polling&t=NboMpZQ HTTP/1.1" 400 -
127.0.0.1 - - [16/May/2021 00:27:31] "GET /socket.io/?EIO=4&transport=polling&t=NboMpZS HTTP/1.1" 400 -
127.0.0.1 - - [16/May/2021 00:27:31] "GET /socket.io/?EIO=4&transport=polling&t=NboMpZR.0 HTTP/1.1" 400 -
127.0.0.1 - - [16/May/2021 00:27:31] "GET /socket.io/?EIO=4&transport=polling&t=NboMpZR HTTP/1.1" 400 -

【问题讨论】:

【参考方案1】:

The Flask SocketIO documentation 这么说:

如果传入的 HTTP 或 WebSocket 请求包含 Origin 标头,则此标头必须与连接 URL 的方案和主机匹配。如果不匹配,则返回 400 状态码响应并拒绝连接。

还有这个:

如有必要,可使用 cors_allowed_origins 选项来允许其他来源。此参数可以设置为字符串以设置单个允许的来源,或设置为列表以允许多个来源。 '*' 的特殊值可用于指示服务器允许所有来源,但应谨慎操作,因为这可能使服务器容易受到跨站点请求伪造 (CSRF) 攻击。

所以不要这样:

socketio = SocketIO(app)

你可以这样做:

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

与 cors 问题无关,但我还在函数中添加了 return 语句。没有返回我得到的东西:

TypeError:视图函数没有返回有效响应。

如果使用 @cross_origin() 装饰器似乎是必需的,因此您也可以删除它们,然后您就不需要返回语句。

【讨论】:

除了进行您建议的更改之外,我还删除了 @cross_origins() 装饰器,它现在可以工作了。 是的,如果您不使用 @cross_origins() 装饰器,您似乎不需要返回值。

以上是关于使用 Socket.IO 反应和烧瓶 - CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章

/socket.io/* 404 未找到烧瓶

CORS 不适用于 hapijs 和 socket.io

CORS、Laravel Valet 和 Socket.io

使用 Nginx 的 socket.io 出现 CORS 错误

Axios 发布请求被烧瓶制作的 api 拒绝。 CORS错误即将出现[重复]

在 Firefox 中运行 node.js 和 socket.io 时出现 CORS 错误