ASP.NET Core 2.1:在 HTTP POST 验证失败后导航回页面显示浏览器错误
Posted
技术标签:
【中文标题】ASP.NET Core 2.1:在 HTTP POST 验证失败后导航回页面显示浏览器错误【英文标题】:ASP.NET Core 2.1: Navigating back to a page after an HTTP POST fails validation displays a browser error 【发布时间】:2018-07-12 17:50:07 【问题描述】:问题:
使用 ASP.NET Core 2.1 MVC 项目,我在使用浏览器后退按钮返回表单后收到以下浏览器错误消息,其中表单 POST 未通过服务器端验证:
Firefox 中的错误消息:
文档已过期
此文档不再可用。
请求的文档在 Firefox 的缓存中不可用。
作为安全预防措施,Firefox 不会自动重新请求敏感文档。 单击重试以从网站重新请求文档。
Chrome 中的错误消息:
确认重新提交表单
此网页需要您之前输入的数据才能 正确显示。您可以再次发送此数据,但这样做您 将重复此页面之前执行的所有操作。
按重新加载按钮重新提交加载页面所需的数据。
ERR_CACHE_MISS
重现步骤:
-
提交 html 表单帖子,其中服务器端验证失败
导航到不同的 URL
点击浏览器返回按钮,返回表单页面
注意事项:
这似乎与 Antiforgery 系统禁用响应缓存 (https://docs.microsoft.com/en-us/aspnet/core/performance/caching/middleware?view=aspnetcore-2.1) 有关。
Antiforgery 系统用于生成安全令牌以防止 跨站点请求伪造 (CSRF) 攻击设置 Cache-Control 和 Pragma 标头为 no-cache 以便不缓存响应。为了 有关如何禁用 HTML 表单的防伪令牌的信息 元素,请参阅 ASP.NET Core 防伪配置。
我可以确认的是,如果您从 HTML 表单中删除 @Html.AntiForgeryToken()
,浏览器错误消息就会消失。
这在 ASP.NET MVC5 中使用 AntiForgeryToken
不是问题。
问题:
在ASP.NET Core 2.1中,有没有人找到办法继续使用Antiforgery系统,并防止在使用浏览器返回按钮时显示此浏览器错误消息?
这是我的 POST 操作:
[HttpPost]
[ValidateAntiForgeryToken]
[ActionName("Contact-Form")]
public async Task<ActionResult> ContactForm(ContactFormViewModel cfvm)
if (ModelState.IsValid)
// << Handling of the form submit code here >>
TempData["Success"] = string.Format("Your contact request was submitted successfully!");
return RedirectToAction("Contact-Form-Success");
TempData["Error"] = "The form did not submit successfully. Please verify that all of the required fields are filled.";
return View();
更新:
我在 ASP.NET Core Docs 上发布了这个问题: https://github.com/aspnet/Docs/issues/7590
【问题讨论】:
“在使用 AntiForgeryToken 的 ASP.NET MVC5 中不是问题”,“有没有人找到继续使用 Antiforgery 系统并防止出现此浏览器错误消息的方法” 那么是哪一个?你的意思是这不是框架的问题,还是你的问题不是由防伪引起的 Antiforgery 并未在ASP.NET MVC5
中引起此问题,但它现在在 ASP.NET Core 2.1
中引起了问题。我正在将 MVC5 项目迁移到 Core 2.1,这就是我提到旧框架的原因。
我认为当您单击后退按钮时,他说这是 .Net Core 中的一个新问题,尽管我认为出于安全原因出现错误是有道理的,以防他们重新提交表单或干预 ViewState页面..您只需要使用自定义错误页面以礼貌的方式呈现它。
@numbtongue 在没有自定义错误页面的情况下,其他网站如何避免这种情况?我没有看到任何主要网站有这个问题。例如,如果您向 ASP.NET (login.asp.net/account/login) 提交无效登录,然后转到其他页面,然后返回浏览器,则不会在此处显示浏览器错误消息。
如果它是一个单页网站,他们可以管理浏览器历史记录,这样您就不会真正离开该页面,但好问题可能有人可以回答..
【参考方案1】:
这不是特定于语言的问题。这是一种浏览器行为。说这不是 ASP.NET MVC 5 的问题是不正确的。
解决方案: 解决此问题的常用方法是 PRG pattern,它自 1995 年以来一直存在。
可以在here找到一个使用TempData
的ASP.NET Core实现
我认为这个link 对您最有帮助,因为它演示了在 MVC 5 和 MVC 6 中实现的方法。
我希望这会有所帮助!
如果时间允许,我将尝试使用基于剃须刀页面启动项目的示例尽快更新这篇文章。
【讨论】:
我的问题不在于模型状态和“确认表单重新提交”弹出窗口。我遇到的浏览器错误是不同的,我相信是由于Antiforgery
令牌没有被缓存。您的 PRG 答案可能会避免发生此浏览器错误(因为它正在执行新的 GET),但它并没有解决根本问题。如果您可以在 MVC5 中重现浏览器缓存错误,请告诉我,但我只是在升级到 Core 2.1 后才遇到它。
很公平。 ^^
不应缓存防伪令牌。新的提交应该需要一个新的令牌。错误正是您应该看到的。按照这个答案的建议遵循 PRG 模式。
感谢@ChrisPratt 澄清防伪令牌。它让我失望,因为它们曾经被缓存在 MVC5 中。抱歉@AdamVincent 质疑您的答案。将其标记为正确。那么,您链接的关于使用 ModelState 帮助程序实现 TempData
的 ASP.NET Core 1.0 文章,您在 Core 2.1 中仍会使用吗?
@Wellspring 我相信质疑一切!我零冒犯。我看了一下这篇文章,并自己实现了它。我承认,我不喜欢这个解决方案,但它是迄今为止我能找到的最深思熟虑的解决方案。我会支持你在 github.com 上打开的问题。我认为 asp.net 核心团队可以提高开发者的生活质量,这种模式已经存在了很长时间。以上是关于ASP.NET Core 2.1:在 HTTP POST 验证失败后导航回页面显示浏览器错误的主要内容,如果未能解决你的问题,请参考以下文章
AWS负载均衡器后面的ASP.NET Core 2.1 HTTPS重定向?
asp.net core 2.1,Include() 函数不适用于 db first 方法
有没有办法在 ASP.NET Core 2.1 中捕获对 Razor 页面不存在的自定义处理程序的 HTTP 请求?
小5聊Asp.Net Core 2.1 主要依赖那些dll和版本