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

Flask POST页面后退触发confirm form resubmission问题求解

问题原因

浏览器弹出「确认表单重新提交」提示的核心原因是未遵循Post/Redirect/Get(PRG)Web交互模式:

  1. 你的/scanning、/resultcovid两个路由仅支持POST方法,处理完请求逻辑后直接返回渲染后的HTML页面,没有做302跳转。这种实现下,浏览器历史栈中会直接存储这两个POST请求的记录——浏览器默认将POST请求视为带数据修改副作用的操作(比如提交信息、上传文件、下单),后退到历史栈中的POST记录时,出于安全考虑会弹出确认提示,避免未经用户许可重复发送请求造成重复操作。
  2. 你观察到「直接刷新/scanning页面内容正常」,本质是触发刷新时的请求场景和后退场景不一样:如果是提交表单后停留在/scanning返回的页面直接刷新,其实同样会触发表单重提交提示;你遇到的正常显示场景,大概率是通过其他GET路径进入的对应页面,没有走POST请求的历史记录。
修复方案

推荐方案:严格落地PRG模式(最稳妥,无兼容性问题)

核心思路是所有POST请求处理完成后,一律返回302跳转到对应的GET路由,由GET路由负责页面渲染,保证浏览器历史栈中存储的全是无副作用的GET请求,从根源上消除重提交提示。
参考改造代码如下:

# 新增GET路由,负责渲染CT上传页
@app.route('/scan', methods=['GET'])
def scan_page():
    # 校验用户信息是否存在,不存在跳回信息填写页
    if not session.get('email'):
        flash('请先完成个人信息填写')
        return redirect('/user-info-entry') # 替换成你自己的信息填写页路径
    return render_template('scan.html')

# 改造原个人信息提交POST路由
@app.route('/scanning', methods=['POST'])
def scanning():
    # 原有存session逻辑保留
    session["firstname"] = request.form['firstname']
    session["lastname"] = request.form['lastname']
    session["email"] = request.form['email']
    session["phone"] = request.form['phone']
    session["gender"] = request.form['gender']
    session["age"] = request.form['age']
    if len(session.get('email', '')) != 0:
        # 处理完POST直接302跳转到GET类型的上传页
        return redirect('/scan')
    else:
        flash('请填写有效的邮箱地址')
        return redirect(request.url)

# 改造结果页路由,同时支持GET、POST方法
@app.route('/resultcovid', methods=['GET', 'POST'])
def resultc():
    if request.method == 'POST':
        file = request.files['file']
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            flash('影像上传成功,检测结果如下')
            # 原有预测逻辑保留
            img = cv2.imread('static/uploads/'+filename)
            img = cv2.resize(img, (224, 224))
            img = img.reshape(1, 224, 224, 3)
            img = img/255.0
            pred = covid_model.predict(img)
            pred = 1 if pred >= 0.5 else 0
            # 预测结果存入session,供GET请求渲染使用
            session['last_detection'] = {
                'filename': filename,
                'result': pred
            }
            # POST处理完跳转到同路径的GET请求
            return redirect('/resultcovid')
        else:
            flash('仅支持上传png、jpg、jpeg格式的影像文件')
            return redirect('/scan')
    # GET请求逻辑:从session取数据渲染结果页
    detection_data = session.pop('last_detection', None)
    if not detection_data:
        flash('未找到待查看的检测记录,请先上传影像')
        return redirect('/scan')
    return render_template(
        'resultcovid.html',
        filename=detection_data['filename'],
        fn=session.get('firstname'),
        ln=session.get('lastname'),
        age=session.get('age'),
        gender=session.get('gender'),
        r=detection_data['result']
    )

改造完成后,不管是点击后退按钮还是刷新页面,触发的都是GET请求,不会再出现表单重提交提示。

临时备选方案(不推荐长期用)

如果暂时不想调整后端路由结构,可以在表单提交完成后,通过前端JS调用history.replaceState替换当前浏览器历史记录的条目,绕开POST记录的检查。但这种方式兼容性差,清理缓存、强制刷新场景下仍可能出现问题,仅适合临时应急。

注意:不要尝试通过修改页面缓存头(比如Cache-Control、Pragma)解决这个问题,该提示是浏览器历史栈对POST请求的默认安全机制,和缓存策略无关。

内容的提问来源于stack exchange,提问作者Raghul Rover

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 10:48:18