Изменилось ли поведение формы сообщения в современных браузерах? (или как двойные клики обрабатываются браузером)

Справочная информация. Мы в процессе написания страницы регистрации/оплаты, и наша философия заключалась в том, чтобы сначала скопировать всю проверку и проверку ошибок на стороне сервера, а затем добавить проверку на стороне клиента в качестве второго шага (un-obstructive jQuery).

Мы хотели отключить двойную кликов на стороне сервера, поэтому мы написали некоторый код блокировки, потокобезопасный для обработки одновременных сообщений/условий гонки. Когда мы попытались проверить это, мы поняли, что мы не можем вызывать одновременное сообщение или состояние гонки.

Я думал, что (в старых браузерах в любом случае) двойной щелчок кнопки отправки работал следующим образом:

  • Пользователь дважды нажимает кнопку отправки.
  • Браузер отправляет сообщение при первом щелчке
  • Во втором клике браузер отменяет/игнорирует начальную запись и инициирует вторую запись (до того, как первая почта вернулась с ответом).
  • Браузер ждет возврата второго сообщения, игнорируя исходный ответ.

Я думал, что со стороны сервера это выглядит так: сервер получает два одновременных почтовых запроса, выполняет и отвечает им обоим (не подозревая, что никто не слушает первый ответ).

Из нашего тестирования (FireFox 3.0, IE 8.0) это то, что на самом деле происходит:

  • Кнопка двойного нажатия кнопки пользователя
  • Браузер отправляет сообщение для первого щелчка
  • Браузер приостанавливает второй клик, но ждет ответа от первого щелчка.
  • Ответ возвращается с первого щелчка (ответ игнорируется?).
  • Браузер отправляет сообщение для второго клика.

Итак, с сервера: сервер получает отдельную запись, которую он выполняет и отвечает. Затем сервер получает второй запрос, который он выполняет и отвечает.

Мой вопрос в том, что это всегда срабатывало так (и я схожу с ума)? Или это новая функция в современных браузерах, которая предотвращает отправку одновременных сообщений на сервер?

Кажется, что для предотвращения двойного клика на стороне сервера нам не нужно беспокоиться о одновременных постах или условиях гонки. Только нужно беспокоиться о поставленных в очередь сообщениях.

Заранее благодарим за любые отзывы/комментарии.

Алекс

Ответ 1

Аналогичная ситуация, с которой вам приходится обращаться (что приложение javascript disable-submit-button не распространяется) - это тот, на который пользователь нажимает кнопку "Отправить", сервер обрабатывает запрос, но пока он обрабатывает интернет-соединение пользователя, (возможно, они находятся на поезде, идущем в туннель).

Когда поезд выходит из туннеля, пользователь не знает, была ли успешна их транзакция или нет - они нажали кнопку, но ничего не изменилось на странице (или, возможно, у них появилась страница "Попробовать еще раз" ). Естественно, что для этого нужно снова нажать кнопку "Отправить" (или кнопку "Попробовать еще раз" ).

Лучший способ справиться с этой ситуацией - включить уникальный идентификатор транзакции в форму (в скрытом поле). Генерируйте этот идентификатор произвольно, и когда транзакция успешно обработана, сохраните ее в базе данных в списке завершенных транзакций.

Затем, когда вы получите 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

Это имеет то преимущество, что (если у вас есть база данных, которая должным образом поддерживает транзакции), и поскольку вы обрабатываете платежи, я надеюсь, что вы это делаете!) вам не нужно делать какие-либо потоки или блокировки - вещи "просто работают" ".

(хотя будьте осторожны - некоторые системы баз данных могут произвольно прервать ваши транзакции, если есть проблема с concurrency, но эта (редкая) ситуация легко справляется с использованием цикла повтора...)

Что касается тестирования двойных кликов из браузеров: не имеет значения, если вы нажмете кнопку "stop" между двумя нажатиями "отправить"?

Ответ 2

Это может быть глупый ответ, но почему бы вам просто отключить кнопку отправки с javascript при щелчке, так что вам не нужно беспокоиться о нескольких кликах. я обычно делаю это на большинстве форм, которые я делаю, и это, кажется, решает проблему.

Вы уже сказали, что используете javascript, так что это не проблема?

Ответ 3

Пока запрос находится на этапе подключения или отправки, нажатие на отправку во время первого представления отменяет запрос, запустив новый, не зная "сервер".