Flask中/start路由Session未更新的问题排查请求
Flask寻宝应用Session异常问题分析
问题现象
在Google Colab运行基于Flask的寻宝应用时,出现以下异常:
- 输入正确密码后,
/check_password路由中已成功更新Session,但/start路由无法获取更新后的Session,页面重复显示相同线索; - 仅在第二次输入错误密码或空值时,
/start路由才能获取到更新后的Session。
核心原因分析
1. 前端表单默认提交与AJAX请求并发冲突
前端代码中,提交按钮为type="submit",且未阻止表单默认提交行为:
<button id="popupButton" type="submit">Submit</button>
点击按钮时会同时触发两个并行请求:
- 自定义AJAX POST请求到
/check_password(用于验证密码并更新Session); - 表单默认的GET请求(提交到当前页面,即
/start路由)。
由于请求并行处理,GET请求可能先于POST请求完成Session更新前到达服务器,导致/start路由读取到未更新的旧Session,页面显示旧线索。POST请求完成后Session虽已更新,但此时页面已加载完成,直到下一次请求(如输错密码后的请求)才会读取到新Session。
2. Flask Session的Cookie同步时机问题
Flask的Session通过Cookie存储,只有服务器返回响应时才会将更新后的Session Cookie发送给浏览器。AJAX请求返回JSON响应时,浏览器会更新Cookie,但此时表单默认提交的GET请求已完成,使用的仍是旧Cookie,因此无法获取最新Session数据。
解决方案
1. 阻止表单默认提交行为
在前端点击事件中添加event.preventDefault(),取消表单默认提交,仅保留AJAX请求:
document.getElementById('popupButton').addEventListener('click', (event) => { // 阻止表单默认提交行为 event.preventDefault(); const password = document.getElementById('password').value; const currentIndex = parseInt(currentIndexInput.value); fetch('/check_password', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: `password=${password}`, }) .then((response) => response.json()) .then((data) => { if (data.success) { currentIndexInput.value = currentIndex + 1; document.querySelector('h2').textContent = 'I++ - Treasure Hunt'; document.querySelector('p').textContent = data.clue; // 若需要更新code,补充以下代码 // document.querySelector('.code-display').textContent = data.code; } }) .catch((error) => { console.error('Error:', error); }); });
同时建议移除表单action属性,避免意外提交:
<form class="overlay" id="popupOverlay" action="">
2. 简化Session更新逻辑(可选)
当前Session更新代码正确,可简化写法保持清晰:
if entered_password == required_password: session['unique_indices'].pop(0) session['num'] = 1 session.modified = True
验证效果
修改后,点击提交按钮仅发送AJAX请求,等待服务器更新Session并返回新线索后,前端再更新页面内容,避免并发请求导致的Session读取异常,确保每次正确提交后页面显示最新线索。
内容的提问来源于stack exchange,提问作者Hello World
相关产品推荐
相关产品推荐

