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

Фон: Мы находимся в процессе записи страницы регистрации/оплаты, и наша философия должна была кодировать всю проверку и проверку ошибок на стороне сервера сначала, и затем добавить клиентскую проверку как второй шаг (компактный jQuery).

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

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

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

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

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

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

Таким образом от стороны сервера: Сервер получает единственное сообщение, которое он выполняет и отвечает на. Затем сервер получает второй запрос, который он выполняет и отвечает на.

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

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

Заранее спасибо за любую обратную связь / комментарии.

Alex

12
задан Alex Czarto 7 May 2010 в 21:53
поделиться

3 ответа

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

0
ответ дан 2 December 2019 в 23:31
поделиться

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

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

1
ответ дан 2 December 2019 в 23:31
поделиться

Похожая ситуация, которую вам нужно решить (которую не покрывает решение 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

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

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

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

.
4
ответ дан 2 December 2019 в 23:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: