Изменилось ли поведение формы сообщения в современных браузерах? (или как двойные клики обрабатываются браузером)
Справочная информация. Мы в процессе написания страницы регистрации/оплаты, и наша философия заключалась в том, чтобы сначала скопировать всю проверку и проверку ошибок на стороне сервера, а затем добавить проверку на стороне клиента в качестве второго шага (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
Пока запрос находится на этапе подключения или отправки, нажатие на отправку во время первого представления отменяет запрос, запустив новый, не зная "сервер".