Ответ 1
Попробуйте использовать блокировку Redis и окружайте свой блок чем-то вроде
Redis.current.lock("#{current_user.id}.action_name") do
# Some code
end
Это драгоценный камень, который я использую https://github.com/mlanett/redis-lock
Ну, все в заголовке, но я объясню немного больше: -)
В моем приложении rails есть много форм (Ajaxified или нет).
Чтобы пользователи не отправляли два или более некоторых формы, я использую Javascript.
Там мой сценарий для Ajaxified формы:
Теперь Я хочу добавить код на стороне сервера, чтобы он был действительно чистым, если пользователь обошел javascript.
Любые предложения?
Попробуйте использовать блокировку Redis и окружайте свой блок чем-то вроде
Redis.current.lock("#{current_user.id}.action_name") do
# Some code
end
Это драгоценный камень, который я использую https://github.com/mlanett/redis-lock
Вы можете добавить параметр: disable_with = > "Подождите..." в тег submit.
Я использую 4 метода для 4 сценариев, прежде всего, предпочитаю мой тэнер здесь: Предотвращать двойные отправки в форме AJAX Rails
используйте stopImmediatePropagation и добавьте событие click к целевому dom.
/**
* 防止按钮重复点击。
* NOTICE: #1 需要在作用点之前调用此方法 #2 stopImmediatePropagation 会阻止后面的所有事件包括事件冒泡
* @delay_duration 两次点击的间隔时间
*/
$.fn.preventMultipleClick = function (delay_duration) {
delay_duration = delay_duration || 3000;
var last_click_time_stamp = 0;
var time_duration = 0;
$(this).bind('click', function (event) {
time_duration = last_click_time_stamp ? event.timeStamp - last_click_time_stamp : 0;
//console.debug("preventMultipleClick", last_click_time_stamp, time_duration);
if (time_duration && time_duration < delay_duration) {
event.stopImmediatePropagation();
} else {
//console.debug("skip preventMultipleClick~");
last_click_time_stamp = event.timeStamp;
}
});
};
используйте атрибут ajax beforeSend.
/**
* 使用:
* 在jquery的ajax方法中加入参数:beforeSend
* 例如:beforeSend: function(){return $.preventMultipleAjax(event, 5000)}
*
* @param event
* @param delay_duration
* @returns {boolean}
*/
$.preventMultipleAjax = function (event, delay_duration) {
delay_duration = delay_duration || 3000;
var target = $(event.target);
var last_click_time_stamp = target.attr("_ajax_send_time_stamp") || 0;
var time_duration = last_click_time_stamp ? event.timeStamp - last_click_time_stamp : 0;
//console.debug("preventMultipleAjax", last_click_time_stamp, time_duration);
if (time_duration && time_duration < delay_duration) {
return false;
} else {
//console.debug("skip preventMultipleAjax~");
target.attr("_ajax_send_time_stamp", event.timeStamp);
return true;
}
};
<%= f.submit "Save annotation", :disable_with => "Saving...", :class => "btn btn-primary", :id => "annotation-submit-button" %>
или: отключить: 仅仅 对 表单 元素, 按钮 等 起作用, 会 阻止 其 上 的 事件 触发
<input type="submit" value="submit" />
<input type="button" value="button" />
<input type="image" value="image" />
Это драгоценный камень: https://github.com/mlanett/redis-lock
Redis.current.lock("#{current_user.id}.action_name") do
# Some code
end
Вот что я сделал бы:
Это не будет препятствовать двойному представлению, но, по крайней мере, предотвратит изменения со второго фиксации. То есть когда пользователь отправляет форму во второй раз, код проверяет поданный токен на тот, что находится в базе данных, и если они не совпадают - не делайте обновления для объекта.
Это также имеет откат для вновь созданных объектов (т.е. если пользователь хочет создать комментарий или smth, как это). Но в этом случае вы можете проверить временной интервал создания от того же пользователя, и если он меньше, скажем, 5 секунд, вы не позволили бы "создать" объект.
Не настоящее предложение (я не удивлюсь нисходящим), но будет ли ваш сайт по-прежнему использоваться без JS? Как насчет того, чтобы показать ему соответствующее сообщение, что для нормальной работы ему нужно включить JS, иначе вы не будете показывать ему много и много форм на странице.
1) Приятно также показать некоторый движущийся индикатор, чтобы пользователь знал, что что-то происходит, что их запрос обрабатывается. Он должен устранить множество двойных представлений.
2) Если пользователь отключил javascript, как вы собираетесь отправлять 'ajaxified' формы? Если сайт становится недействительным без javascript, то, вероятно, лучше всего просто уведомить пользователя (например, Eimantas).
изменить
Один пример такого показателя, просто чтобы понять, что я имею в виду в 1.
http://www.netzgesta.de/busy/
Не уверен, что это полезно:
ПО СЕРВЕРУ:
При новой загрузке формы, установить сеанс ['variable'] = false//означает, что форма еще не отправлена.
В форме submit проверьте:
if session['variable'] == true
{
do nothing...
}
else
{
set session['variable'] = true;
//do submit logic here
}