You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 17:06:02