有哪些方法可以在ASP.NET MVC中停止多个表单回发?

时间:2009-05-20 16:29:59

标签: asp.net-mvc postback submit action-filter

常见的Web问题是用户多次单击表单的提交按钮,因此服务器会多次处理表单。当用户点击已提交表单的后退按钮并因此再次处理时,也会发生这种情况。

阻止ASP.NET MVC发生这种情况的最佳方法是什么?

我认为的可能性是:

  1. 提交后禁用该按钮 - 这会绕过多次点击而不是导航
  2. 让接收操作立即重定向 - 浏览器似乎将这些重定向保留在历史记录之外
  3. 在会话和表单中放置一个唯一标记 - 如果它们匹配处理表单 - 如果不清除表单以进行新提交
  4. 还有更多吗?

    是否有任何特定的实施?

    我可以看到第三个选项被实现为具有HtmlHelper扩展名的ActionFilter,其方式与防伪手段类似。

    期待收到MVC'ers的消息。

6 个答案:

答案 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:

Blog post is here