Flask(Python)路由间共享变量时session取值为None的问题排查
问题描述
我尝试在Flask中使用session在多个路由之间共享变量,使用的代码如下:
from flask import Flask, jsonify, request, session from flask_cors import CORS from flask_session import Session app = Flask(__name__) CORS(app) SESSION_TYPE = 'filesystem' app.config.from_object(__name__) app.secret_key = 'abc' @app.route("/getinputData", methods = ['POST']) def getData(): inputData = json.loads(request.data) molID = inputData["ID"] searchType = inputData["searchType"] session["sharedmolID"] = molID session["sharedsearchType"] = searchType return inputData @app.route("/querydatabyMol", methods = ['GET']) def querydatabyMol(): sharedmolID = session.get("sharedmolID", None) sharedsearchType = session.get("sharedsearchType", None) print(sharedmolID) print(sharedsearchType) return sharedmolID if __name__ == '__main__': app.run(debug=True) sess = Session() sess.init_app(app)
但调用第二个路由打印变量时,我得到的返回值是None。我目前暂时通过全局变量解决了该问题,但我了解到全局变量非线程安全,因此希望改用session实现跨路由变量共享。
问题原因
你的代码一共存在3个核心问题:
- Flask-Session初始化位置错误:你把Session实例化、初始化绑定app的代码写在了
app.run()之后。Flask服务启动后会持续阻塞在app.run()逻辑里,后面的初始化代码永远不会执行,相当于你根本没有启用配置的文件系统类型session,实际运行的是Flask默认的基于签名Cookie的session。 - 跨域请求未配置凭证携带:你使用了
flask-cors处理跨域,但默认配置下跨域请求不会携带Cookie这类身份凭证,后端无法将两次请求关联到同一个session,每次请求都会生成独立的新session,自然读不到之前存入的值。 - 缺少依赖导入:POST路由中使用了
json.loads()解析请求数据,但代码顶部没有导入json模块,接口实际运行时会直接抛出名称错误。
修正方案
- 把Flask-Session的初始化逻辑移动到
app.run()之前,保证服务启动时完成session存储的初始化。 - 初始化CORS时开启
supports_credentials=True配置,允许跨域请求携带凭证。 - 补充缺失的
json模块导入。 - 前端发送请求时需要同步开启凭证携带配置:如果使用axios需要设置
withCredentials: true,如果使用fetch需要设置credentials: 'include'。
修正后的参考代码:
# 补充缺失的json导入 import json from flask import Flask, jsonify, request, session from flask_cors import CORS from flask_session import Session app = Flask(__name__) # 开启跨域凭证支持 CORS(app, supports_credentials=True) SESSION_TYPE = 'filesystem' app.config.from_object(__name__) app.secret_key = 'abc' # 把Session初始化移动到app.run之前 sess = Session() sess.init_app(app) @app.route("/getinputData", methods = ['POST']) def getData(): inputData = json.loads(request.data) molID = inputData["ID"] searchType = inputData["searchType"] session["sharedmolID"] = molID session["sharedsearchType"] = searchType return inputData @app.route("/querydatabyMol", methods = ['GET']) def querydatabyMol(): sharedmolID = session.get("sharedmolID", None) sharedsearchType = session.get("sharedsearchType", None) print(sharedmolID) print(sharedsearchType) return sharedmolID if __name__ == '__main__': app.run(debug=True)
注意:如果你是前后端分离部署,不要把前端页面和后端接口部署在不同的一级域名下,否则Cookie跨域携带会被浏览器默认安全策略拦截,本地开发阶段用本地代理、测试/生产环境配置同域部署即可避免该问题。
内容的提问来源于stack exchange,提问作者María
相关产品推荐
相关产品推荐

