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

Flask-Session与CORS异常:跨请求Session为空,部分请求CORS失败

Flask-Session跨端点丢失Session及CORS异常问题解决

问题概述

遇到CORS异常,导致Flask-Session无法在不同端点的请求间保留变量,前后端无法正常传递Cookie。具体表现:

  • 前端运行在http://localhost:3000,后端运行在http://localhost:5000
  • 首次请求/file_upload成功,后端生成对应Session ID并设置session['test'] = 0
  • 第二次请求/allin_6_9时,后端生成新的Session ID,读取session['test']触发KeyError,返回500错误
  • 浏览器控制台显示CORS错误
  • 已更新所有依赖至最新版本:Flask 3.0.0、Werkzeug 3.0.1、Flask-Cors 4.0.0、Flask-Session 0.5.0

原前端代码

import React, { useState } from "react";
import "./App.css";

const uploadFile = async () => {
  if (!file) return;
  
  setIsLoading(true);
  try {
    const formData = new FormData();
    formData.append("file", file);
    const response = await fetch(
      `${URI}/file_upload`,
      {
        method: "POST",
        body: formData,
      },
      { credentials: 'include' } // 错误:fetch仅接受两个参数,此配置未生效
    );
    
  } catch (error) {
     ...
    }
  }

原后端代码

from flask import Flask, session
from flask_session import Session
from flask_cors import CORS, cross_origin

app = Flask(__name__)

app.secret_key = 'BAD_SECRET_KEY'
UPLOAD_FOLDER = 'uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

app.config['SESSION_TYPE'] = 'filesystem'

Session(app)
# 错误:supports_credentials=True时,origins不能设为通配符*
CORS(app, supports_credentials=True, resources={r"*": {"origins": "*"}}, withCredentials = True)

@app.route('/file_upload', methods=['POST'])
@cross_origin(supports_credentials=True) # 重复配置,可能引发冲突
def upload_parse_file():
    # some code here
    ...
    print('sessions_sid', session.sid)
    session['test'] = 0
    return 'OK'

@app.route('/allin_6_9', methods=['POST'])
@cross_origin(supports_credentials=True) # 重复配置,可能引发冲突
def rfi():
    print('sessions_sid', session.sid)
    print('session test is', session['test'])
    return 'OK'

问题根源与修复方案

1. 前端fetch参数错误

fetch API仅接受两个参数:请求URL和配置对象。原代码将credentials: 'include'作为第三个参数传入,导致该配置未生效,浏览器不会携带Cookie到后端。

修复后前端代码:

import React, { useState } from "react";
import "./App.css";

const uploadFile = async () => {
  if (!file) return;
  
  setIsLoading(true);
  try {
    const formData = new FormData();
    formData.append("file", file);
    const response = await fetch(
      `${URI}/file_upload`,
      {
        method: "POST",
        body: formData,
        credentials: 'include' // 移至第二个参数的配置对象中
      }
    );
    
  } catch (error) {
     ...
    }
  }

注意:所有跨域请求(包括/allin_6_9的请求)都需要添加credentials: 'include'配置。

2. 后端CORS配置冲突

当启用supports_credentials=True时,浏览器不允许将origins设为通配符*,这是CORS安全规范的要求。同时,全局配置CORS后,无需再给每个路由添加@cross_origin装饰器,重复配置可能导致冲突。

修复后后端CORS配置:

# 替换原CORS配置,指定具体前端Origin
CORS(app, supports_credentials=True, resources={r"*": {"origins": "http://localhost:3000"}})

移除所有路由上的@cross_origin(supports_credentials=True)装饰器。

3. Flask Session Cookie跨域配置

跨域场景下,需要确保Session Cookie的SameSite属性设置正确,否则浏览器不会在跨域请求中携带Cookie。

在后端添加以下配置:

# 跨域场景下,SameSite设为None,同时开启Secure(本地http环境可临时关闭,生产环境必须开启)
app.config['SESSION_COOKIE_SAMESITE'] = 'None'
app.config['SESSION_COOKIE_SECURE'] = False # 本地http开发用False,生产环境改True

# 本地开发可省略Domain配置,浏览器会自动处理localhost
# app.config['SESSION_COOKIE_DOMAIN'] = 'localhost'

4. 完整修复后后端代码

from flask import Flask, session
from flask_session import Session
from flask_cors import CORS

app = Flask(__name__)

app.secret_key = 'BAD_SECRET_KEY'
UPLOAD_FOLDER = 'uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

# Session配置
app.config['SESSION_TYPE'] = 'filesystem'
app.config['SESSION_COOKIE_SAMESITE'] = 'None'
app.config['SESSION_COOKIE_SECURE'] = False # 本地http开发用False,生产环境改True

Session(app)
# CORS配置:指定具体Origin,启用credentials
CORS(app, supports_credentials=True, resources={r"*": {"origins": "http://localhost:3000"}})

@app.route('/file_upload', methods=['POST'])
def upload_parse_file():
    # some code here
    ...
    print('sessions_sid', session.sid)
    session['test'] = 0
    return 'OK'

@app.route('/allin_6_9', methods=['POST'])
def rfi():
    print('sessions_sid', session.sid)
    # 添加容错处理,避免KeyError导致500
    test_value = session.get('test', 'default_value')
    print('session test is', test_value)
    return 'OK'

验证步骤

  1. 重启后端服务
  2. 前端发起/file_upload请求,查看浏览器Application面板的Cookie,确认已设置Session Cookie
  3. 发起/allin_6_9请求,查看后端日志,两次请求的session.sid应一致,session['test']能正常读取

内容的提问来源于stack exchange,提问作者Vladimir Kuzmenkov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 01:18:15