76

我想检查服务器端对我的 php 页面的请求是否是 ajax 请求。

我看到了两种方法:

第一种方式:在请求中发送一个GET参数,告诉页面这是一个 AJAX 请求 (= mypage.php?ajax)

我的页面.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');

我的页面.php:

if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest' ) {
    //request is ajax
}

事实是,这两种方法很容易被黑客入侵,因此检查我是否收到这样的 AJAX 请求并不安全。

如何检查我是否收到 AJAX 请求?

4

8 回答 8

70

这是实现结果的教程

例子:

if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')
{    
  exit;    
}
continue;

这将检查HTTP_X_REQUESTED_WITH参数是否不为空,如果它等于xmlhttprequest,那么它将退出脚本。

于 2014-01-28T16:54:57.960 回答
40

没有可靠的方法知道请求是通过 Ajax 发出的。您永远不能相信来自客户端的数据。您可以使用几种不同的方法,但可以通过欺骗轻松克服它们。

于 2013-08-15T19:49:43.477 回答
14

从带有空合并运算符的 PHP 7 开始,它会更短:

$is_ajax = 'xmlhttprequest' == strtolower( $_SERVER['HTTP_X_REQUESTED_WITH'] ?? '' );
于 2018-05-11T06:32:47.350 回答
11

为您网站上包含当前页面名称的每个页面(实际页面不包括或 rpcs)设置一个会话变量,然后在您的 Ajax 调用中传递一个用$_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;
?>

编辑:仅供参考,我设置随机数的方式只适用于一个小时并更改,因此如果他们在过去一小时或 2 小时内没有刷新执行 ajax 调用的页面,则 ajax 请求将失败。

于 2013-11-18T03:51:39.787 回答
8

Yii PHP 框架使用这个函数来检查 AJAX 调用。

public function isAjax() {
  return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest';
}
于 2018-01-17T13:30:20.270 回答
5
$headers = apache_request_headers();
$is_ajax = (isset($headers['X-Requested-With']) && $headers['X-Requested-With'] == 'XMLHttpRequest');
于 2014-06-25T13:32:48.080 回答
1

试试下面的代码片段

if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) 
   && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') 
  {
    /* This is one ajax call */
  }
于 2019-08-09T08:22:38.930 回答
-7

您可以尝试使用$_SESSION变量来确保请求是从浏览器发出的。否则,您可以通过数据库或文件 [服务器端] 发送请求。

于 2013-08-15T19:53:36.177 回答