ASP.NET项目如何防止浏览器回退按钮触发表单重复提交?
问题根因
你的问题核心是当前POST请求处理完成后直接返回视图,没有遵循Post/Redirect/Get(PRG)设计模式:浏览器会将POST请求的响应页标记为POST类型的历史记录,用户点击回退按钮时默认会触发POST请求重发,导致重复生成短链接。
标准解决方案:PRG模式改造
POST处理完成后重定向到GET接口,生成的短链接通过TempData传递(TempData可在重定向后保留一次读取),改造后代码如下:
[HttpPost] [ValidateAntiForgeryToken] public ActionResult ShortenURL(ShortURLModel model) { if (ModelState.IsValid) { var currentDomain = GetCurrentAbsoluteURL(); Tuple<bool, string> response = _shortUrlProcessor.CreateShortURL(model.originalURL, model.shortURL); if (response.Item1) { // 生成短链成功后存到TempData TempData["ShortenURLSuccess"] = true; TempData["shortlink"] = currentDomain + response.Item2; // 重定向到GET接口,不要直接返回View return RedirectToAction(nameof(ShortenURL)); } else { ViewBag.ShortenURLSuccess = false; } } // 校验失败/生成失败时返回当前视图,保留用户输入和错误提示 return View(); } [HttpGet] [Route("{*id}")] public IActionResult ShortenURL(string id) { ViewBag.currentdomain = GetCurrentAbsoluteURL(); if (id == null) { // 从TempData读取短链生成结果 if (TempData["ShortenURLSuccess"] != null) { ViewBag.ShortenURLSuccess = (bool)TempData["ShortenURLSuccess"]; ViewBag.shortlink = TempData["shortlink"]?.ToString(); // 可选:保留TempData让用户刷新页面也能看到短链,不需要就去掉这行 TempData.Keep(); } return View(); } var originalURL = _shortUrlProcessor.GetOriginalURL(id); if (originalURL == null) { return Redirect("~/"); } return Redirect(originalURL); }
方案说明
改造后POST请求处理完成后会触发一次302跳转,浏览器会用GET方法请求短链生成页,此时历史记录里的条目就是GET类型,用户回退时只会触发GET请求,不会重复提交表单。
如果不需要保留生成的短链接,希望用户回退直接看到空表单,去掉GET方法里的TempData读取逻辑即可。
如果不想用PRG模式,也可以用前端方案解决:提交表单成功后调用history.replaceState(null, null, window.location.href)替换当前历史记录,手动把当前页的请求类型标记为GET,回退时也不会触发POST重发。
内容的提问来源于stack exchange,提问作者CodeMuppet
相关产品推荐
相关产品推荐

