Coldfusion - Как предотвратить множественные клики?

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

Это может произойти, когда у пользователя низкая скорость соединения и во время обновления страницы он снова нажимает кнопку.

Как мне справиться с этой ситуацией? Я хоть и отключаю кнопку но по другим причинам это невозможно.

<a class="msg" href="/manage/conversations.cfm?destination=#destination#">
        #ucase(request.l('Send'))#
</a>

Спасибо за уделенное время


person WiTHS4UC3    schedule 23.06.2015    source источник
comment
Вы говорите о кнопке и показываете тег привязки. Пожалуйста, устраните несоответствие.   -  person Dan Bracuk    schedule 23.06.2015
comment
@DanBracuk вот оно :)   -  person WiTHS4UC3    schedule 23.06.2015
comment
Почему это помечено как ColdFusion? Это проблема на стороне клиента.   -  person Scott Stroz    schedule 23.06.2015
comment
@DanBracuk Вы понимаете, что с помощью CSS тег привязки может выглядеть как кнопка, верно?   -  person Dave Ferguson    schedule 23.06.2015
comment
Посмотрите на второй ответ, он может быть полезен: stackoverflow. ком/вопросы/4699352/   -  person volume one    schedule 24.06.2015
comment
Почему нельзя отключить ссылку/кнопку?   -  person Scott Stroz    schedule 28.06.2015


Ответы (3)


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

Однако, чтобы решить проблему с пользовательским интерфейсом, вы можете напрямую связать вызов функции, а не файл cf.

<a class="msg" href="javascript: processLink(#destination#);">
        #ucase(request.l('Send'))#
</a>

<script>
runCount = 0;

function processLink(destination){
runCount++;

if (runCount == 1){
 window.location.href = "/manage/conversations.cfm?destination=" + destination;
}

}
</script>
person Dave Ferguson    schedule 23.06.2015
comment
Да, но не делайте runCount локальной переменной функции, иначе значение всегда будет 1. - person Leigh; 23.06.2015
comment
@Leigh Хороший улов .. Я обновил код, чтобы отразить ваш комментарий. - person Dave Ferguson; 23.06.2015

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

Одним из подходов может быть создание скрытого поля формы с идентификатором GUID, который будет создавать coldfusion при рендеринге вашей формы.

Итак, что-то вроде:

<cfset GUID = createUUID()>

<cfoutput>
<form id="frm" action="/target.cfm" method="post">
<input type="hidden" name="guid" value="#GUID#">
<!-- all your formfields go here -->
<input type="submit">
</form>
</cfoutput>

Затем на стороне сервера целевая страница проверяет, не получила ли она ранее GUID. Есть много способов сделать это, вот два из многих способов.

а) Использовать область сеанса.

Это, вероятно, самый быстрый способ, если вы не работаете в кластерной среде и вам просто нужно что-то быстрое для крошечного приложения.

<cfif isDefined("session.MYPAGE_GUID") AND session.MYPAGE_GUID EQ form.guid>
<cfoutput>Duplicate Form Submission</cfoutput>
<cfabort>
<cfelse>
<cfset session.MYPAGE_GUID = form.guid>
<!-- Do Business Logic Here -->
</cfif>

b) Используйте таблицу базы данных. Создайте таблицу базы данных со столбцом с именем GUID. Убедитесь, что GUID является первичным ключом или имеет уникальное ограничение.

Прежде чем запускать бизнес-логику, вставьте form.GUID в таблицу базы данных. Если вы можете выполнить процесс вставки, ваша бизнес-логика, если нет, запрос к базе данных выдаст ошибку, что запись существует. Затем вы можете перехватить эту ошибку и принять соответствующие меры для дублирования отправки.

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

Имейте в виду, что это всего лишь демонстрация основных концепций, а не простое решение. Предстоит еще немного поработать над внедрением этих концепций в решение для электронной коммерции.

person M.Scherzer    schedule 27.06.2015

Лучший способ — отключить ссылку после ее выбора. Если вы не хотите этого делать, альтернативой является структурирование беседы.cfm следующим образом.

<div id="pageContent">
small amount of text
</div>
<cfflush>
</body>
</html>

<cfsavecontent variable = "actualPageContent">
code
</cfsavecontent>

<cfoutput>
<script>
var #toScript(actualPageContent, "newPageContent")#; 
document.getElementById("pageContent").innerHTML = "newPageContent";
</script>
</cfoutput>
person Dan Bracuk    schedule 23.06.2015
comment
Это самый запутанный способ решить простую проблему пользовательского интерфейса. - person Dave Ferguson; 23.06.2015