Flask Session存储含Feature字段数据时返回Null问题求助
解决Flask Session存入长Feature字符串后返回Null的问题
嘿,我太懂你这糟心的情况了——把亚马逊商品的Feature字段(就是那串超长的商品描述)存入Flask Session后,在/profile/<asin>路由里取数据居然返回null,但只要删掉Feature键值对,Session立马恢复正常,价格啥的都能正常读取。而且你已经确认Feature是普通字符串,逻辑也没问题,对吧?
代码重现
存入Session的核心代码
app = Flask(__name__) app.config['SECRET_KEY'] = 'yo' @app.route('/', methods=['GET','POST']) def index(): authenticated_url = authenticate(Availability='Available',Operation='ItemSearch',Keywords=str(query),SearchIndex='Electronics', ResponseGroup='ItemAttributes') product = authenticated_url['ItemSearchResponse']['Items']['Item'] arr = [] for items in product: main_dictionary = {} sub_dictionary = {} sub_dictionary['price'] = items['ItemAttributes']['FormattedPrice'] featureLists = items['ItemAttributes']['Feature'] emptyFeatureStr = ' ' for items in featureLists: emptyFeatureStr += items sub_dictionary['Feature']=emptyFeatureStr main_dictionary[items['ASIN']]=sub_dictionary # 构建以ASIN为键的字典 arr.append(main_dictionary) # 将字典存入数组 session['searchResults']=arr print(session['searchResults']) # 确认此处session已正确设置,字典符合预期
读取Session的路由代码
@app.route('/profile/<asin>', methods=['GET','POST']) def profilePage(asin): return str(session.get('searchResults'))
问题根源
Flask默认的Session是基于Cookie的客户端Session——它会把Session数据加密后存在用户浏览器的Cookie里,而Cookie有严格的大小限制(一般是4KB左右)。你传入的Feature字符串实在太长了,拼接后的数据量直接突破了这个限制,导致整个Session数据没法正常写入Cookie,甚至被截断,所以读取的时候就返回了null。而去掉Feature后,Session的数据量刚好卡在Cookie限制范围内,自然就正常工作了。
解决方案
方案一:改用服务器端Session(最推荐)
用Flask-Session扩展把Session数据存在服务器端(比如Redis、Memcached或者本地文件),彻底摆脱Cookie的大小限制。
操作步骤:
- 安装Flask-Session:
pip install flask-session
- 修改Flask配置(以Redis为例,没有Redis的话可以用
filesystem类型存在本地文件):
from flask import Flask, session from flask_session import Session import redis app = Flask(__name__) app.config['SECRET_KEY'] = 'yo' # 配置Session存储类型为Redis app.config['SESSION_TYPE'] = 'redis' # 连接本地Redis服务,根据你的实际环境修改地址和端口 app.config['SESSION_REDIS'] = redis.Redis(host='localhost', port=6379) # 初始化Session Session(app) # 后续路由代码无需修改,保持原来的逻辑即可
方案二:把长字符串存入数据库,Session仅存标识
如果不想用扩展,可以把Feature的长字符串存入数据库(比如SQLite、MySQL),Session里只存ASIN和对应的数据库记录ID,需要展示Feature时再从数据库查询。
方案三:压缩长字符串(临时缓解,不推荐长期使用)
如果一定要用客户端Session,可以尝试用zlib压缩Feature字符串来减小体积:
import zlib import base64 # 存入Session时压缩 compressed_feature = base64.b64encode(zlib.compress(emptyFeatureStr.encode())).decode() sub_dictionary['Feature'] = compressed_feature # 读取Session时解压 compressed_feature = session_data['Feature'] original_feature = zlib.decompress(base64.b64decode(compressed_feature)).decode()
不过这个方法只是权宜之计,如果字符串实在太长,压缩后还是超过Cookie限制,就没用了,所以优先选方案一。
内容的提问来源于stack exchange,提问作者Biplov




