解决双重提交问题

10 浏览
0 Comments

解决双重提交问题

我想了解Web开发人员如何避免双重提交问题。基本上,我对这个问题的理解如下:\n当一个不耐烦的用户多次提交表单时,会引发问题,这就是双重提交。这个问题可以通过JavaScript(特别是jQuery脚本)来解决,一旦表单提交后,禁用提交按钮,但这种方法的弱点是如果客户端禁用了JavaScript。\n还有一些服务器端的检测方法。\n所以我的问题是:\n人们是如何克服双重提交的?\n双重提交导致的问题的实际例子是什么?\n有没有任何Web应用框架内置的双重提交工具?

0
0 Comments

解决双重提交问题的出现原因是用户快速双击提交按钮或在页面加载完成之前重新提交表单。解决方法有以下几种:

1. 使用重定向-提交后重定向(PRG)模式:当用户提交表单时,先在客户端执行重定向操作,然后跳转到响应页面。这种方法可以消费提交的数据,但无法解决快速双击问题。

2. 禁用提交按钮:在第一次点击后禁用提交按钮,以处理快速双击问题。但是,如果用户禁用了JavaScript,则无法使用此方法。

3. 在表单中添加隐藏字段:在表单中添加一个隐藏字段,用于存储客户端状态,并在提交时将其发送回服务器验证数据的唯一性。

4. 生成随机表单UID/哈希值:生成一个随机的表单UID/哈希值,并将其作为隐藏字段添加到表单中,在提交后将其标记为已处理。

5. 比较数据库中的实际值:始终将提交的数据与数据库中的实际值进行比较,判断是否需要更新数值。但是,这种方法并不总是适用。

解决双重提交问题的方法有很多,但最终的解决方案是使用重定向-提交后重定向模式,并结合其他方法来处理快速双击问题和禁用JavaScript的情况。

0
0 Comments

解决双重提交问题

在使用Java服务器端脚本并且使用Struts 2时,如果遇到双重提交问题,可以参考以下链接:http://www.xinotes.org/notes/note/369/

解决方法是生成并保存一个令牌(token)在session中,当首次提交请求时,将令牌一同提交到Struts的action中,然后在action中开启一个线程,线程名称为令牌ID,执行客户端请求的逻辑。当客户端再次提交相同的请求时,检查线程是否仍在运行(thread.getcurrentthread().interrupted),如果仍在运行,则向客户端返回503重定向。

请参考Struts 2中的ExecuteAndWaitInterceptor代码,结合令牌的逻辑可以解决快速点击的问题。

然而,将令牌保存在session中无法很好地处理并发问题,例如在浏览器的多个标签页中打开同一个网站时。

如果一个用户在浏览器中打开多个标签页,那么令牌可能会混淆,因为仍然只有一个用户会话。

令牌生成在服务器端,并且也存在于cookie中。即使打开多个标签页,令牌也是共享的,因为cookie是在相同的域路径下。

这是一个问题。我打开页面1,想要更新我的个人资料。生成了令牌1。我打开一个新的标签页,想要更新我的个人头像。生成了并存储在会话中的令牌2。我提交标签页1,发送了令牌1,与令牌2不匹配,所以没有提交更改。如果我不幸的话,个人资料页面现在生成了令牌3。我提交我的照片,发送了令牌2,但现在与令牌3不匹配。

用户提出的问题是关于表单提交的:1. 可以在HTML

元素中添加隐藏字段来防止双重提交;2. 一旦用户提交表单,我将重定向到一个包含更改的页面。

但是,令牌保存在会话中并不总是有效,因为它们无法处理多个窗口。

可以通过创建与标签页相关的cookie来解决这个问题。请参考以下链接:bytes.com/topic/javascript/answers/878108-creating-browser-tab-specific-cookie

需要注意的是,该链接显示的是Struts 1的代码,而你提到的是Struts 2。这两个版本是不兼容的。

以上链接可能无法正常工作,可能是该网站更改了实际数据。请更新你的回答。

0
0 Comments

在这个真实生活中的情况中,用户在一个博彩网站上下注。用户会双击,导致下注重复。这不好!JavaScript的检查不足以防止这种情况发生。

解决方法:

1. 使用服务器端脚本语言在渲染表单时创建一个隐藏的UUID/GUID输入。

2. 在表单提交时,立即将其添加到名为UniqueSubmissions的数据库表中。然后继续处理。

3. 如果在UniqueSubmissions表中找到相同的UUID/GUID的每个后续请求都会被拒绝。

这对我们起作用。希望能帮到你的问题!

好了!但是UUID和GUID是什么意思?

添加了UUID/GUID的链接-大多数编程语言都可以通过编程方式创建一个,例如我使用ColdFusion,可以使用createUUID()来创建一个。

你的想法很好。但我认为这种架构在Ajax响应中会面临一些限制。我们如何在不重新渲染页面的情况下更新UUID/GUID呢?

这个对我来说没有问题:document.querySelector("#submitbutton").addEventListener("click",function(ev){ev.target.disabled=true;}); - 假设在点击后页面会刷新,而不是使用XMLHttpRequest或类似的响应。

为什么JavaScript没有起作用,具体的实现是什么?

0