Flask路由中使用AJAX获取的数据为何无法触发test路由的flash消息
问题原因及解决方法
核心问题有4个:
- 没有配置Flask必填的
SECRET_KEY:flash消息依赖session存储,session加密需要密钥,未配置的情况下flash不会生效 - 判断逻辑类型不匹配:
request.args.get()获取的参数是字符串类型,你代码中直接和整数11、10做相等判断,'11' == 11永远返回False,不会触发flash - flash的触发分支永远不会执行:你把flash逻辑写在
test路由的POST请求分支里,但点击按钮只会触发AJAX的GET请求到/get_button_val,不会触发/路由的POST请求,对应分支代码根本不会运行 - 异步请求未触发页面刷新:flash消息只有在模板渲染的时候才会加载到页面,AJAX是异步请求,就算成功设置了flash,页面没有重新渲染的话用户也看不到新消息
修复方案
方案1:简单修复(页面刷新展示flash)
- 先给Flask应用加密钥
app = Flask(__name__) # 新增这一行,生产环境请使用复杂随机字符串 app.secret_key = "test_secret_key_123"
- 调整
button_val里的参数类型,同时触发flash逻辑
@app.route('/get_button_val') def button_val(): resp = request.args.get('resp') print(f'<-- {resp}') # 转成整数存储 data.y = int(resp) # 直接在这里触发flash if data.y == 11: flash('a') if data.y == 10: flash('b') return resp
- 修改前端AJAX逻辑,请求成功后刷新页面加载flash
function onSuccess() { // 请求成功后刷新页面,渲染flash消息 window.location.reload() } function onError() { alert('请求失败') }
方案2:无刷新体验更好的实现(不需要flash)
直接在AJAX响应里返回消息,前端动态插入到页面,不需要刷新页面:
- 修改
button_val路由返回消息
from flask import jsonify @app.route('/get_button_val') def button_val(): resp = request.args.get('resp') print(f'<-- {resp}') resp_int = int(resp) msg = '' if resp_int == 11: msg = 'a' if resp_int == 10: msg = 'b' return jsonify({"msg": msg})
- 前端收到响应后直接插入消息
$(document).ready(function () { $('.button1, .button2').click(function (e) { e.preventDefault(); var val = $(this).attr('data'); $.ajax({ url: '/get_button_val', data: { resp: val }, success: function(res) { // 直接把消息插到页面里,不需要刷新 $('body').append(`<h3>${res.msg}</h3>`) }, error: function() { alert('请求失败') }, }); }); });
额外注意
你目前用全局类变量存数据的方式只适合本地单进程测试,生产环境多进程/多线程部署的时候,全局变量会出现数据错乱,建议用session、数据库或者缓存服务存用户的独立数据。
内容的提问来源于stack exchange,提问作者Not Sure
相关产品推荐
相关产品推荐

