leyu乐鱼






      leyu乐鱼

      网(wǎng)站应用(yòng)程序防止(zhǐ)数据重(chóng)复提(tí)交

      发布于: 2025-07-07    浏览: 62    作者(zhě):系统管理员

      一、前端(duān)防(fáng)护策略(减少无效请求)

      1.按钮禁用与(yǔ)状(zhuàng)态反(fǎn)馈

      ·点击(jī)后立(lì)即禁用按钮,阻(zǔ)止(zhǐ)二次点击,并添加加载动画提示用户(hù):document.getElementById("btnSubmit").addEventListener("click", function() {

      this.disabled = true;

      this.classList.add("loading-spinner"); // 添加加载样(yàng)式(shì)

      });

      2.防抖(Debounce)与(yǔ)请求锁

      ·通过标志(zhì)位或定时器限制(zhì)短(duǎn)时间内的重(chóng)复提交:

      let isSubmitting = false;functionsubmitForm() {

      if (isSubmitting) return;    

      isSubmitting = true;// 执行提交逻辑

      }

      ·框架中可使用lodash.debounce优(yōu)化

      3.异步提交 + Loading提(tí)示

      ·使用Ajax提交(jiāo)数据,配合模(mó)态框或进(jìn)度条增(zēng)强用户(hù)体验:

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

       e.preventDefault();    

      $("#loadingModal").show(); // 显示加载(zǎi)提(tí)示    

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

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

      });

      });



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

      1.Token令牌(pái)机制

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


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

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

      Session["SubmitToken"] = token;    

      ViewBag.Token = token; // 传递到(dào)视(shì)图

      }
      [HttpPost]

      public ActionResult SubmitForm(FormModel model, string token){

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

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

      }

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


      2.幂等键(Idempotency Key)

      ·客户端(duān)生成唯一Key(如GUID)放入请求头,服务端通过缓存(Redis/MemoryCache)校验:

      // ASP.NET Core 过滤器示(shì)例

      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.重定向模式(PRG: Post-Redirect-Get)

      ·提(tí)交(jiāo)成(chéng)功后返回302重定向至结果页,刷新时仅(jǐn)重发GET请求,避免重复POST。


       三、数(shù)据(jù)库与架构层防护

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

      ·为业(yè)务关键字段(duàn)(如订单号、用(yòng)户邮箱)添加唯一索引,从底层阻(zǔ)止重复数据:

      ALTERTABLE Orders ADDUNIQUE (OrderNumber);



      2.分布式(shì)锁(Redis)

      ·以“用(yòng)户(hù)ID + 操作类型”为Key加(jiā)锁,确保并发请求仅一个生效:

      // Redis锁(suǒ)示例

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

      redisLock.ReleaseLock();

      }


      3.操(cāo)作状(zhuàng)态校验

      ·更新数据(jù)前检查状态(如订单是否已(yǐ)处理),避免(miǎn)重(chóng)复更新:

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



      总结

      ·基础方(fāng)案(àn):前端按钮禁用 + 后端Token校(xiào)验(yàn)(覆盖90%场景(jǐng))

      ·高可(kě)靠场景:补充数据库唯一索引与Redis分布式锁

      ·用户体验优化:加载动画与防(fáng)抖减少用户焦虑性(xìng)点击





      在线客服(fú)

      leyu乐鱼

      leyu乐鱼