簡體   English   中英

如何使用 PHP 檢查請求是否是 AJAX 請求

[英]How to check if the request is an AJAX request with PHP

我想檢查服務器端對我的 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 請求?

這是實現結果的教程

例子:

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

這將檢查HTTP_X_REQUESTED_WITH參數是否不為空,如果它等於xmlhttprequest ,那么它將退出腳本。

沒有可靠的方法知道請求是通過 Ajax 發出的。 您永遠不能相信來自客戶端的數據。 您可以使用幾種不同的方法,但可以通過欺騙輕松克服它們。

從帶有空合並運算符的 PHP 7 開始,它會更短:

$is_ajax = 'xmlhttprequest' == strtolower( $_SERVER['HTTP_X_REQUESTED_WITH'] ?? '' );

為您網站上包含當前頁面名稱的每個頁面(實際頁面不包括或 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 請求將失敗。

Yii PHP 框架使用這個函數來檢查 AJAX 調用。

public function isAjax() {
  return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest';
}
$headers = apache_request_headers();
$is_ajax = (isset($headers['X-Requested-With']) && $headers['X-Requested-With'] == 'XMLHttpRequest');

試試下面的代碼片段

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

嘗試使用 HTTP_SEC

  if (!array_key_exists("HTTP_SEC_FETCH_SITE",$_SERVER) || $_SERVER["HTTP_SEC_FETCH_SITE"] != "same-origin")
    die(header("HTTP/1.1 404 Not Found"));
  if (!array_key_exists("HTTP_SEC_FETCH_MODE",$_SERVER) || $_SERVER["HTTP_SEC_FETCH_MODE"] != "cors")
    die(header("HTTP/1.1 404 Not Found"));
  if (!array_key_exists("HTTP_SEC_FETCH_DEST",$_SERVER) || $_SERVER["HTTP_SEC_FETCH_DEST"] != "empty")
    die(header("HTTP/1.1 404 Not Found"));

您可以嘗試使用$_SESSION變量來確保請求是從瀏覽器發出的。 否則,您可以通過數據庫或文件 [服務器端] 發送請求。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM