Несколько месяцев назад у нас произошел крупный сбой в работе SharePoint, потому что пользователь зажал клавиатуру таким образом, что кнопка Enter была нажата бесконечно. Пользователь находился на настроенной странице поиска людей, и сотни POST-сообщений от одного и того же пользователя были отправлены асинхронно, что привело к перегрузке сервера.
Поскольку я работаю в крупной организации, я ищу более глобальный способ предотвратить это.
Есть ли способ предотвратить многократную отправку веб-форм обычным пользователем в течение короткого периода времени в IIS?
Я знаю, что мы можем написать javascript для отключения кнопки после ее нажатия, но мы надеемся предотвратить возникновение этой проблемы на других страницах, где может существовать аналогичная возможность.
Обновить: Похоже, глядя на исходный код, javascript выполняет document.location = url всякий раз, когда нажимается код клавиши 13 (Enter). Опять же, мы можем написать JS, чтобы предотвратить это в этом месте, но мы также хотим иметь возможность защититься от такого рода проблем в более общем плане ... предпочтительно на уровне IIS.
Если проблема заключается просто в том, чтобы избежать воздействия из-за количества одновременных запросов, существует надстройка для IIS 7, динамические ограничения IP. (Эта возможность теперь встроена в IIS8). Это можно настроить для режима «только журнал», чтобы определить возможные последствия до включения возможности.
http://www.iis.net/downloads/microsoft/dynamic-ip-restrictions
Отправка нескольких форм должна рассматриваться на уровне приложения. Это тривиально легко реализовать с помощью главных страниц. Следующий jquery на главной странице выполняет трюк для всех дочерних страниц содержимого:
$("form").submit(function () {
$(":submit", this).attr("disabled", "disabled");
});
Еще одна хорошая практика, которую стоит принять: Post / Redirect / Get
Один из вариантов - ограничение скорости с помощью чего-то вроде http://www.iis.net/downloads/microsoft/dynamic-ip-restrictions который может быть настроен на блокировку оскорбительного IP-адреса на установленный период времени.
Вы, конечно, захотите определить типичные запросы / секунду / IP, прежде чем вводить что-то подобное в производство, но это должно помешать одному пользователю снова сделать что-то подобное.
Вы можете написать модуль IIS глобального уровня и проверить, поступает ли тот же запрос от одного и того же пользователя в течение определенного короткого времени. тогда вы можете решить, разрешить ли выполнение запроса или нет.
class CGlobalTestFilterModule:public CGlobalModule
{
public:
GLOBAL_NOTIFICATION_STATUS
OnGlobalPreBeginRequest(IN IPreBeginRequestProvider * pProvider)
{
...
}
...
}
вот хорошее руководство по реализации модулей IIS: http://www.iis.net/learn/develop/runtime-extensibility/develop-a-native-cc-module-for-iis вы можете выбрать управляемые модули, если вы больше знакомы с .NET