现代浏览器中的表单帖子行为有变化吗? (或浏览器如何处理双击)

时间:2010-05-07 21:48:02

标签: html browser error-handling postback double-click

背景:我们正在编写注册/付款页面,我们的理念是首先在服务器端编写所有验证和错误检查,然后添加客户端验证作为第二步(un -obstructive jQuery)。

我们想要禁用双击服务器端,因此我们编写了一些锁定的,线程安全的代码来处理同时发布的/竞争条件。当我们试图对此进行测试时,我们意识到我们不能同时发生后期或竞赛条件。

我认为(无论如何在旧浏览器中)双击提交按钮的工作原理如下:

  
      
  • 用户双击提交按钮。
  •   
  • 浏览器在第一次点击时发送帖子
  •   
  • 在第二次点击时,浏览器取消/忽略初始帖子,并发起第二篇帖子(在第一篇帖子返回之前有回复)。
  •   
  • 浏览器等待返回第二个帖子,忽略初始帖子回复。
  •   

我认为从服务器端看起来像这样:服务器获得两个同时发布的请求,执行并响应它们(不知道没有人正在听第一个响应)。

根据我们的测试(FireFox 3.0,IE 8.0),实际情况如下:

  
      
  • 用户双击提交按钮
  •   
  • 浏览器发送第一次点击的帖子
  •   
  • 浏览器排队第二次点击,但等待第一次点击的响应。
  •   
  • 首次点击时返回响应(忽略响应?)。
  •   
  • 浏览器会发送第二次点击的帖子。
  •   

因此,从服务器端:服务器接收它执行并响应的单个帖子。然后,服务器接收它执行的第二个请求并响应。

我的问题是,这总是以这种方式工作(我会失去理智)吗?或者这是现代浏览器中的一项新功能,可防止将同时发布的内容发送到服务器?

似乎对于服务器端双击预防,我们不必担心同时发布的帖子或竞争条件。只需要担心排队的帖子。

提前感谢您的任何反馈/意见。

亚历

3 个答案:

答案 0 :(得分:4)

您需要处理的类似情况(javascript disable-submit-button解决方案未涵盖)是用户单击Submit,服务器处理请求,但在处理用户的Internet连接时下来(也许他们坐火车进入隧道)。

当火车离开隧道时,用户不知道他们的交易是否成功 - 他们按下按钮,但页面上没有任何变化(或者他们可能有“再试一次”页面)。他们自然要做的就是再次点击提交(或“再试一次”按钮)。

处理这种情况的最佳方法是在表单中包含唯一的事务ID(在隐藏字段中)。随机生成此id,并在成功处理事务时,将其存储在已完成事务列表的数据库中。

然后当你收到POST时,检查是否已经看到此事务 - 如果已经看到,则直接跳到状态页面。大致是:

BEGIN TRANSACTION

SELECT *
FROM completedTransactions
WHERE userId = ... AND transactionId = ...

<if we got a result - display results of previous transaction>

<otherwise - process the request as normal>

INSERT INTO completedTransactions (userId, transactionId)
VALUES (....)

END TRANSACTION

这样做的好处是(假设您有一个正确支持交易的数据库 - 并且因为您正在处理付款,我希望您这样做!)您不需要进行任何类型的线程或锁定 - 事情“只是工作”

(虽然要小心 - 如果存在并发问题,某些数据库系统可以随意中止您的事务 - 但使用重试循环很容易处理这种(罕见的)情况......)

关于测试来自浏览器的双击:如果您在两次“提交”点击之间按“停止”按钮,会有什么不同吗?

答案 1 :(得分:1)

这可能是一个愚蠢的回应,但是为什么你不要在点击时使用javascript禁用提交按钮,这样你就不必担心多次点击。我通常在我制作的大多数表格上都这样做,似乎解决了这个问题。

你已经说过你正在使用javascript,这不是问题吗?

答案 2 :(得分:0)

只要请求处于连接或发送阶段,在第一次提交期间单击“提交”将取消请求,在没有服务器“知道”的情况下启动新请求。