我有以下控制器:
[HttpPost]
public ActionResult SomeMethod(string foo, obj bar)
{
//Some Logic
}
现在假设从一个Button或Ajax(带有一些编辑)调用Action,我不想收到双重请求。
从服务器端处理此问题的最佳方法是什么?
您首先必须定义符合的时间间隔 双重要求的标准 - Jonesopolis
假设在这种情况下双重请求是指第一次和第二次通话之间的时间差小于1s
答案 0 :(得分:5)
然而,这里的一个重要规定是你必须在某处记录,这需要一段时间。它可能只有几毫秒,但这可能足以让重复请求进入,特别是如果用户双击提交按钮,这通常是双重提交的原因。
Web服务器只是在请求进入时响应请求,重要的是,它有多个线程,甚至可能有多个进程同时处理请求。 HTTP是一种无状态协议,因此服务器不关心客户端之前是否发出了相同的请求,因为它实际上并不知道客户端之前发出了相同的请求。如果两个重复的请求几乎同时在两个不同的线程上提供,那么它就是一个竞赛,看看是否可以设置一个标识另一个的东西作为副本,然后另一个检查它是否重复。换句话说,在大多数情况下,您只是运气不好,无论您尝试做什么服务器端停止重复,这两个请求都会通过。
防止双提交的唯一可靠方法是使用JavaScript禁用提交时的提交按钮。然后,即使双击,用户也只能有效点击一次。当然,如果用户禁用JavaScript,这仍然无法帮助您,但这种情况越来越少。
答案 1 :(得分:4)
看。这种方法很棒。您将在服务器端添加最复杂的控制权。
首先,您需要识别多个请求何时来自同一用户。
我认为在服务器端控制它是最好的方法。
但是,如果你真的想要......看:https://stackoverflow.com/a/218919/2892830
在此链接中建议维护令牌列表。但是,在您的情况下,只需检查是否多次收到相同的令牌。
答案 2 :(得分:0)
您至少需要实现双击事件监听器。
添加测试代码以查看谁负责
如果(IsPostBack) {
_CtrlName = thisPage.Request.Params.Get("__EVENTTARGET");
if (_CtrlName != null && _CtrlName == myButton.ID)
{
//Do your thing
}
}
在页面加载中检查IsPostBack并正确使用它以防止重复请求。
受保护的无效Page_Load(对象发送者,EventArgs e) {
if (!IsPostBack)
{
}
}