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

如何解决Flask+DynamoDB应用中浏览器刷新导致表单重复提交的问题

解决Flask表单提交后刷新重复插入DynamoDB的问题

这个问题太常见了——当你通过POST请求提交表单后,浏览器会把这次POST请求的内容保存下来,点击刷新按钮时,浏览器就会重新发送一遍相同的POST请求,自然就导致DynamoDB里被重复插入数据了。最标准且彻底的解决方案是使用PRG模式(Post/Redirect/Get),下面结合你的代码给出具体修改方案:

方法一:实现PRG模式(推荐)

核心逻辑:处理完POST请求后,不直接返回渲染好的模板,而是重定向到一个GET请求路由(可以是同一个路由的GET分支),同时用Flask的flash机制传递操作提示信息。这样刷新时只会发送GET请求,不会触发重复提交。

修改后的Flask后端代码

from flask import Flask, request, render_template, redirect, url_for, flash

# 初始化app时必须设置secret_key,flash功能依赖它
app = Flask(__name__)
app.secret_key = 'your_random_secret_key_here'  # 替换成任意随机字符串即可

@app.route('/',methods = ['GET','POST'])
def parseurl():
    if request.method == 'GET':
        return render_template('index.html')
    else:
        mesg = ''
        if "url" in request.form and "name" in request.form:
            URL = request.form.get("url")
            if validators.url(URL):
                org_name = request.form.get("name")
                trans = {
                    'url': URL,
                    'organization_name': org_name
                }
                try:
                    table.put_item(Item=trans)
                    mesg = 'Data Saved Successfully'
                except Exception as e:
                    # 打印异常方便调试(生产环境可去掉或改为日志记录)
                    print(f"Insert error: {str(e)}")
                    mesg = 'Data Insertion Not Successful'
            else:
                mesg = 'Not a valid URL'
        else:
            mesg = 'Incomplete Form Data Submitted'
        
        # 用flash存储提示信息,然后重定向到GET请求的同一路由
        flash(mesg)
        return redirect(url_for('parseurl'))

修改后的HTML前端代码

需要替换原来的结果展示区域,改为渲染flash消息:

<body>
    <!-- Navbar-->
    <nav class="navbar navbar-dark bg-dark">
        <span class="navbar-brand mb-0 h1">SCRAPE DATA</span>
    </nav>
    <br>
    <h3 style="margin: auto;width: 80%; text-align: center; margin-top: 20px; text-transform: uppercase">SCRAPE DATA</h3>
    <div class="container">
        <!-- 新增:显示flash提示消息 -->
        {% with messages = get_flashed_messages() %}
            {% if messages %}
                {% for message in messages %}
                    <div id="result">
                        <strong style="color:red">{{ message }}</strong>
                    </div>
                {% endfor %}
            {% endif %}
        {% endwith %}
        
        <form action = "{{url_for('parseurl')}}" method ="POST" >
            <div class="form-group">
                <label for="name">Enter Organization Name</label>
                <input type="text" class="form-control" id="name" name="name" required>
                <label for="url">Enter URL to scrape</label>
                <input type="text" class="form-control" id="url" name="url" required>
            </div>
            <br>
            <div class="form-group">
                <input class="btn btn-primary" type="submit" value="Scrape">
            </div>
        </form>
    </div>
</body>

方法二:前端辅助禁用提交按钮(可选,配合PRG使用更佳)

为了避免用户快速多次点击提交按钮导致的重复提交,可以在前端添加简单的JS代码,点击提交后立即禁用按钮:

<!-- 修改form标签,添加onsubmit事件 -->
<form action = "{{url_for('parseurl')}}" method ="POST" onsubmit="disableSubmit()">
    <!-- 其他表单内容不变 -->
    <div class="form-group">
        <input class="btn btn-primary" type="submit" value="Scrape" id="submitBtn">
    </div>
</form>

<script>
function disableSubmit() {
    const submitBtn = document.getElementById('submitBtn');
    submitBtn.disabled = true;
    submitBtn.value = 'Submitting...';
}
</script>

为什么PRG能解决问题?

当处理完POST请求后返回重定向响应,浏览器会自动发送一个GET请求到目标路由。此时浏览器的历史记录中只会保留GET请求,刷新时只会重新发送GET请求,不会触发POST提交,从根源上避免了重复插入数据的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 15:17:45