365上市公司(英国)集团-官方网站




    365上市公司(英国)集团-官方网站

    网站应用程序防止数据重复提交

    发(fā)布于(yú): 2025-07-07    浏览: 49    作者:系统管理员

    一(yī)、前端防护策略(减少无效请(qǐng)求(qiú))

    1.按钮禁用与状态反馈

    ·点击后立即(jí)禁用(yòng)按钮,阻止二次点击,并添加加载(zǎi)动画提示用户:document.getElementById("btnSubmit").addEventListener("click", function() {

    this.disabled = true;

    this.classList.add("loading-spinner"); // 添加(jiā)加载样式

    });

    2.防(fáng)抖(Debounce)与请求锁(suǒ)

    ·通过标志位或定(dìng)时器限制短时(shí)间内的重复(fù)提交:

    let isSubmitting = false;functionsubmitForm() {

    if (isSubmitting) return;    

    isSubmitting = true;// 执行提(tí)交逻辑

    }

    ·框架(jià)中可使用lodash.debounce优化(huà)

    3.异步提交 + Loading提示

    ·使用Ajax提交数据,配合模态框或进度条增(zēng)强用户体验:

    printf("hello world!");$("#form").submit(function(e) {   

     e.preventDefault();    

    $("#loadingModal").show(); // 显示加载提示    

    $.post("/submit", $(this).serialize(), function() {        

    $("#loadingModal").hide();    

    });

    });



    二、后端幂等性控制(核心防御)

    1.Token令牌机制

    ·流程(chéng):生(shēng)成页面(miàn)时创建唯一Token(如GUID)存入Session,嵌入表单隐(yǐn)藏(cáng)域;提交(jiāo)时校验Token有(yǒu)效性(xìng)并立即销毁。


    // ASP.NET MVC 示例(lì)public ActionResult SubmitForm(){

    string token = Guid.NewGuid().ToString();    

    Session["SubmitToken"] = token;    

    ViewBag.Token = token; // 传递到视图

    }
    [HttpPost]

    public ActionResult SubmitForm(FormModel model, string token){

    if (Session["SubmitToken"]?.ToString() != token) return Content("重复提交拒绝");    

    Session.Remove("SubmitToken");// 处理(lǐ)业务

    }

    ·优势:有效防御刷新、后退导致的重复提交


    2.幂(mì)等键(jiàn)(Idempotency Key)

    ·客(kè)户端生成(chéng)唯一Key(如GUID)放入请(qǐng)求(qiú)头(tóu),服(fú)务端(duān)通过缓存(cún)(Redis/MemoryCache)校验:

    // ASP.NET Core 过(guò)滤(lǜ)器(qì)示例

    publicclassIdempotencyFilter : IAsyncActionFilter{   

     public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next){        

    var key = context.HttpContext.Request.Headers["Idempotency-Key"].FirstOrDefault();        if (_cache.TryGetValue(key, out _))    context.Result = new BadRequestResult();        

    else    _cache.Set(key, true, TimeSpan.FromMinutes(5));        

    await next();    

    }

    }


    3.重定(dìng)向模式(PRG: Post-Redirect-Get)

    ·提(tí)交(jiāo)成功后(hòu)返回302重定向(xiàng)至结果页,刷(shuā)新时仅重(chóng)发(fā)GET请求(qiú),避免重复(fù)POST。


     三、数据(jù)库(kù)与(yǔ)架构层防护

    1.数据(jù)库唯一约(yuē)束

    ·为业务(wù)关键字段(如订单号、用户邮箱)添加唯一索引,从底层阻止(zhǐ)重复数据:

    ALTERTABLE Orders ADDUNIQUE (OrderNumber);



    2.分(fèn)布式锁(Redis)

    ·以“用户(hù)ID + 操作类(lèi)型”为Key加锁(suǒ),确保并发请求仅一个生效:

    // Redis锁示(shì)例

    if (redisLock.AcquireLock(userId + "_submit"TimeSpan.FromSeconds(10))){    // 执行业务    

    redisLock.ReleaseLock();

    }


    3.操作状态校验

    ·更新(xīn)数(shù)据前检查(chá)状态(如订单是否已处理),避免重(chóng)复更(gèng)新:

    UPDATE Orders SET Status ='Paid'WHERE Id =100AND Status ='Pending';



    总结

    ·基础(chǔ)方案:前端按钮禁用 + 后端(duān)Token校验(覆盖90%场景)

    ·高可靠场(chǎng)景:补充数(shù)据库唯一索引与Redis分布式锁

    ·用户体验优(yōu)化:加载动画与防抖减少(shǎo)用户焦虑性点(diǎn)击(jī)





    在线客服

    365上市公司(英国)集团-官方网站

    365上市公司(英国)集团-官方网站