PHP AJAX 回调的服务器端速率限制?
PHP Server-side rate limit on AJAX callbacks?
我将 PHP 与 AJAX 结合使用以实现我网站上的许多功能。我用 Javascript 在客户端实现了一种速率限制系统。基本上,在单击按钮后将其禁用 1 秒。
虽然这对于更无辜的情况来说效果很好,但我觉得我也需要在服务器端的东西来限制请求。
基本上,我希望用户每秒可以进行的最大调用次数为 AJAX。事实上,每秒一个似乎是合理的。
一种方法是以某种方式将每个请求记录到我的 AJAX 回调中,并在发出新请求之前从 table 中读取。但这会极大地增加我的服务器和数据库的工作负载。
有没有其他方法可以做到这一点?
PHP
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' );
jQuery
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();
}
我将 PHP 与 AJAX 结合使用以实现我网站上的许多功能。我用 Javascript 在客户端实现了一种速率限制系统。基本上,在单击按钮后将其禁用 1 秒。
虽然这对于更无辜的情况来说效果很好,但我觉得我也需要在服务器端的东西来限制请求。
基本上,我希望用户每秒可以进行的最大调用次数为 AJAX。事实上,每秒一个似乎是合理的。
一种方法是以某种方式将每个请求记录到我的 AJAX 回调中,并在发出新请求之前从 table 中读取。但这会极大地增加我的服务器和数据库的工作负载。
有没有其他方法可以做到这一点?
PHP
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' );
jQuery
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();
}