常见的Web问题是用户多次单击表单的提交按钮,因此服务器会多次处理表单。当用户点击已提交表单的后退按钮并因此再次处理时,也会发生这种情况。
阻止ASP.NET MVC发生这种情况的最佳方法是什么?
我认为的可能性是:
还有更多吗?
是否有任何特定的实施?
我可以看到第三个选项被实现为具有HtmlHelper扩展名的ActionFilter,其方式与防伪手段类似。
期待收到MVC'ers的消息。
答案 0 :(得分:16)
通常人们会忽略最常用的处理方式,即使用 nonce keys 。
你可以像其他人提到的那样使用 PRG ,但PRG的缺点是它无法解决双击问题,它需要额外的服务器之旅重定向,并且由于最后一步是GET请求,因此您无法直接访问刚发布的数据(尽管它可以作为查询参数传递或在服务器端维护)。
我喜欢Javascript解决方案,因为它在大多数时间。
Nonce keys 然而,一直都在工作。随机数密钥是由服务器生成的随机唯一GUID(也保存在数据库中)并嵌入在表单中。当用户POST表单时,nonce键也会被发布。一旦POST进入服务器,服务器就会验证其数据库中是否存在nonce密钥。如果是,则服务器从数据库中删除密钥并处理该表单。因此,如果用户POST两次,则不会处理第二个POST,因为在处理第一个POST后删除了nonce密钥。
nonce密钥具有额外的优势,因为它通过阻止replay attacks(中间的人嗅探你的HTTP请求,然后将其重放到将其视为合法的服务器)来带来额外的安全性。
答案 1 :(得分:5)
您应该始终将重定向作为HTTP响应返回到POST。当用户使用浏览器中的前进/后退按钮来回导航时,这将阻止POST再次发生。
如果您担心用户双击提交按钮,只需让一个小脚本在提交时立即禁用它们。
答案 2 :(得分:2)
您可能需要查看Post-Redirect-Get(PRG)模式:
答案 3 :(得分:1)
这确实不是MVC特有的,但我们在网页上遵循的模式是使用AJAX调用而不是整页POST执行操作。因此,导航到URL永远不会执行操作,只显示表单。 AJAX调用不会在历史记录中
答案 4 :(得分:0)
除了禁用按钮之外,您还可以在整个网页上添加透明div,以便单击不执行任何操作。我们在我的工作中这样做,并添加一个友好的标签说处理请求..
答案 5 :(得分:0)
我找到的最优雅的解决方案是使用ActionFilters: