Как проверить, является ли запрос AJAX-запросом с PHP
Я хотел бы проверить на стороне сервера, является ли запрос на мою php-страницу запросом ajax или нет.
Я видел два способа сделать это:
Первый способ: отправка GET
параметр в запросе, который сообщает странице, что это запрос AJAX (=mypage.php?ajax
)
файла mypage.на PHP:
if(isset($_GET['ajax'])) {
//this is an ajax request, process data here.
}
Второй способ: Установите заголовок в xmlHttpRequest
:
клиентская сторона js:
xmlHttpRequestObject.open(“GET”,url,true);
xmlHttpRequestObject.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
файла mypage.на PHP:
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest' ) {
//request is ajax
}
дело в том,, эти два способа сделать это можно легко взломать, поэтому небезопасно проверять, получаю ли я такой запрос AJAX.
как я могу проверить, получаю ли я запрос AJAX?
7 ответов
нет надежного способа узнать, что запрос был сделан через Ajax. Нельзя доверять данным, поступающим от клиента. Вы можете использовать несколько различных методов, но их можно легко преодолеть с помощью спуфинга.
здесь учебник достижения результата.
пример:
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')
{
exit;
}
continue;
Это проверяет, является ли
HTTP_X_REQUESTED_WITH
параметр не пуст и если он равенxmlhttprequest
, затем он выйдет из скрипта.
установите переменную сеанса для каждой страницы на вашем сайте (фактические страницы не включают или rpcs), которая содержит текущее имя страницы, затем в вашем вызове ajax передайте nonce, соленое с $_SERVER ['SCRIPT_NAME']:
<?php
function create_nonce($optional_salt='')
{
return hash_hmac('sha256', session_id().$optional_salt, date("YmdG").'someSalt'.$_SERVER['REMOTE_ADDR']);
}
$_SESSION['current_page'] = $_SERVER['SCRIPT_NAME'];
?>
<form>
<input name="formNonce" id="formNonce" type="hidden" value="<?=create_nonce($_SERVER['SCRIPT_NAME']);?>">
<label class="form-group">
Login<br />
<input name="userName" id="userName" type="text" />
</label>
<label class="form-group">
Password<br />
<input name="userPassword" id="userPassword" type="password" />
</label>
<button type="button" class="btnLogin">Sign in</button>
</form>
<script type="text/javascript">
$("form.login button").on("click", function() {
authorize($("#userName").val(),$("#userPassword").val(),$("#formNonce").val());
});
function authorize (authUser, authPassword, authNonce) {
$.ajax({
type: "POST",
url: "/inc/rpc.php",
dataType: "json",
data: "userID="+authUser+"&password="+authPassword+"&nonce="+authNonce
})
.success(function( msg ) {
//some successful stuff
});
}
</script>
тогда в rpc вы вызываете тест, который вы прошли, если это хорошо, то шансы довольно велики, что ваш rpc был законно назван:
<?php
function check_nonce($nonce, $optional_salt='')
{
$lasthour = date("G")-1<0 ? date('Ymd').'23' : date("YmdG")-1;
if (hash_hmac('sha256', session_id().$optional_salt, date("YmdG").'someSalt'.$_SERVER['REMOTE_ADDR']) == $nonce ||
hash_hmac('sha256', session_id().$optional_salt, $lasthour.'someSalt'.$_SERVER['REMOTE_ADDR']) == $nonce)
{
return true;
} else {
return false;
}
}
$ret = array();
header('Content-Type: application/json');
if (check_nonce($_POST['nonce'], $_SESSION['current_page']))
{
$ret['nonce_check'] = 'passed';
} else {
$ret['nonce_check'] = 'failed';
}
echo json_encode($ret);
exit;
?>
edit: FYI, как я его установил, nonce хорош только на час и меняется, поэтому, если у них есть не обновлена страница, выполняющая вызов ajax в последний час или 2 запрос ajax завершится ошибкой.
$headers = apache_request_headers();
$is_ajax = (isset($headers['X-Requested-With']) && $headers['X-Requested-With'] == 'XMLHttpRequest');
эта функция используется в Yii framework для проверки вызовов ajax.
public function isAjax() {
return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest';
}
из PHP 7 с нулевым оператором объединения будет короче:
$is_ajax = 'XMLHttpRequest' == ( $_SERVER['HTTP_X_REQUESTED_WITH'] ?? '' );
вы можете попробовать использовать $_SESSION
переменная, чтобы убедиться, что запрос был сделан из браузера. В противном случае вы можете отправить запрос через базу данных или файл [на стороне сервера].