Я использую PHP в сочетании с AJAX для многих функций на моем сайте. Я реализовал своего рода систему ограничения скорости на стороне клиента с Javascript. По сути, отключение кнопки на 1 секунду после нажатия.
Хотя это работает отлично для более невинных случаев, но я чувствую, что мне нужно что-то на стороне сервера, чтобы также ограничивать запросы.
По сути, я хочу, чтобы у пользователей было максимальное количество вызовов AJAX, которые они могут совершать в секунду. На самом деле, один в секунду кажется разумным.
Одним из способов было бы как-то регистрировать каждый запрос к моему обратному вызову AJAX и читать из этой таблицы до того, как будет сделан новый запрос. Но это очень увеличило бы рабочую нагрузку на мой сервер и базу данных.
Есть ли альтернативные способы сделать это?
function comment_upvote_callback() {
// Some sort of rate limit??// $_POST data validation
// Add upvote to database
// Return success or error
}
add_action( 'wp_ajax_comment_upvote_callback', 'comment_upvote_callback' );
var is_clicked = false;
if ( is_clicked == false ) {
$('#comments').on('click', '.comment-upvote', function(event) {
event.preventDefault();
// Button disabled as long as isClicked == true
isClicked = true;
// Data to be sent
var data = {
'action': 'comment_upvote_callback',
'security': nonce,
'comment_id': comment_id
};
// Send Data
jQuery.post(ajaxurl, data, function(response) {
// Callback
// Client-side rate limit
setTimeout( function() {
is_clicked = false;
}, 1000);
});
});
}
Как уже говорилось выше, вы должны использовать ограничение скорости на стороне сервера
Я написал код для реализации того же. Вы можете скопировать код в файл и просто включить его в свой серверный скрипт вверху. Он принимает максимум 3 удара / 5 секунд. Вы можете изменить тариф в соответствии с вашими потребностями
session_start();
const cap = 3;
$stamp_init = date("Y-m-d H:i:s");
if( !isset( $_SESSION['FIRST_REQUEST_TIME'] ) ){
$_SESSION['FIRST_REQUEST_TIME'] = $stamp_init;
}
$first_request_time = $_SESSION['FIRST_REQUEST_TIME'];
$stamp_expire = date( "Y-m-d H:i:s", strtotime( $first_request_time )+( 5 ) );
if( !isset( $_SESSION['REQ_COUNT'] ) ){
$_SESSION['REQ_COUNT'] = 0;
}
$req_count = $_SESSION['REQ_COUNT'];
$req_count++;
if( $stamp_init > $stamp_expire ){//Expired
$req_count = 1;
$first_request_time = $stamp_init;
}
$_SESSION['REQ_COUNT'] = $req_count;
$_SESSION['FIRST_REQUEST_TIME'] = $first_request_time;
header('X-RateLimit-Limit: '.cap);
header('X-RateLimit-Remaining: ' . ( cap-$req_count ) );
if( $req_count > cap){//Too many requests
http_response_code( 429 );
exit();
}
Других решений пока нет …