Flask SocketIO与Angular socket.io-client的CORS策略错误求助
Flask + Angular WebSocket 跨域连接问题解决
我正在学习用Flask和Angular构建WebSocket应用,但始终无法解决CORS跨域问题。尽管已配置CORS允许跨域,Angular客户端仍无法连接到Flask服务端的WebSocket。以下是测试用的极简代码:
server.py
from flask import Flask from flask_socketio import SocketIO, send, emit from flask_cors import CORS, cross_origin app = Flask(__name__) app.config['SECRET_KEY'] = 'secret!' socketio = SocketIO(app, cors_allowed_origins="*") CORS(app) @socketio.on('message') @cross_origin() def handle_message(data): print('received message: ' + data) send("test message that should be sent") if __name__ == '__main__': socketio.run(app, host="localhost")
app.component.html
<div *ngFor="let message of messageList"> <li> {{message}} </li> </div> <input [(ngModel)]="newMessage" (keyup)="$event.keyCode == 13 && sendMessage()" /> <button (click)="sendMessage()">Send Message</button>
app.component.ts
import { Component, OnInit } from '@angular/core'; import { WebsocketService } from './services/websocket.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit{ newMessage = ''; messageList: string[] = []; constructor(private websocket: WebsocketService){ } ngOnInit(){ this.websocket.getNewMessage().subscribe((message: string) => { this.messageList.push(message); }) } sendMessage() { this.websocket.sendMessage(this.newMessage); this.newMessage = ''; } }
websocket.service.ts
import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import { io } from 'socket.io-client'; @Injectable({ providedIn: 'root' }) export class WebsocketService { public message$: BehaviorSubject<string> = new BehaviorSubject(''); constructor() {} socket = io('http://localhost:5000'); public sendMessage(message: any) { console.log('sendMessage: ', message) this.socket.emit('message', message); } public getNewMessage = () => { this.socket.on('message', (message) =>{ this.message$.next(message); }); return this.message$.asObservable(); }; }
错误说明
浏览器返回CORS相关错误,提示无法建立WebSocket连接,具体表现为请求缺少Access-Control-Allow-Origin响应头。
解决步骤
1. 清理无效的CORS配置
flask-cors仅处理普通HTTP请求,WebSocket的握手请求由Flask-SocketIO独立处理,因此不需要CORS(app)和@cross_origin()装饰器,保留SocketIO自身的CORS配置即可:
修改后的server.py:
from flask import Flask from flask_socketio import SocketIO, send app = Flask(__name__) app.config['SECRET_KEY'] = 'secret!' # 仅保留SocketIO的CORS配置,允许所有来源 socketio = SocketIO(app, cors_allowed_origins="*") @socketio.on('message') def handle_message(data): print('received message: ' + data) send("test message that should be sent") if __name__ == '__main__': socketio.run(app, host="localhost", debug=True) # 开启debug便于查看连接日志
2. 确保版本兼容
Flask-SocketIO与socket.io-client必须使用协议兼容的版本,否则会导致握手失败(常被误认为CORS错误):
- 服务端安装指定版本:
pip install flask-socketio==5.3.5
- 客户端安装对应版本:
npm install socket.io-client@4.6.1
3. 增加连接错误监听(可选)
在Angular的WebSocket服务中添加错误监听,方便排查连接问题:
修改后的websocket.service.ts:
import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import { io, Socket } from 'socket.io-client'; @Injectable({ providedIn: 'root' }) export class WebsocketService { public message$: BehaviorSubject<string> = new BehaviorSubject(''); private socket: Socket; constructor() { this.socket = io('http://localhost:5000'); // 添加连接错误监听 this.socket.on('connect_error', (error) => { console.error('WebSocket连接错误:', error); }); this.socket.on('disconnect', () => { console.log('WebSocket断开连接'); }); } public sendMessage(message: any) { console.log('sendMessage: ', message) this.socket.emit('message', message); } public getNewMessage = () => { this.socket.on('message', (message) =>{ this.message$.next(message); }); return this.message$.asObservable(); }; }
4. 验证端口与运行状态
- Flask服务默认运行在5000端口,确保该端口未被占用;
- Angular应用默认运行在4200端口,与Flask端口无冲突;
- 启动Flask服务时确认控制台无报错,启动Angular应用后查看浏览器控制台的连接日志。
内容的提问来源于stack exchange,提问作者Zaga
相关产品推荐
相关产品推荐

