在開發 AJAX 介面時,常需區分「普通頁面請求」與「AJAX 請求」以返回不同格式資料(HTML vs JSON)或執行不同邏輯。主流 JS 框架會自動添加 X-Requested-With: XMLHttpRequest 標頭,PHP 可透過 $_SERVER['HTTP_X_REQUESTED_WITH'] 偵測。
<?php
function isAjaxRequest(): bool {
return !empty($_SERVER['HTTP_X_REQUESTED_WITH'])
&& strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest';
}
// 使用範例
if (isAjaxRequest()) {
// AJAX 請求:返回 JSON
header('Content-Type: application/json');
echo json_encode(['status' => 'ok', 'data' => $data]);
} else {
// 普通請求:渲染完整頁面
include 'view/page.php';
}
| 框架/庫 | 自動發送 X-Requested-With | 備註 |
|---|---|---|
| jQuery | 是 | $.ajax、$.get、$.post 等 |
| Axios | 是 | 預設開啟 |
| Fetch API | 否 | 需手動添加:headers: {'X-Requested-With': 'XMLHttpRequest'} |
| Vue Resource | 是 | |
| Angular $http | 是 |
此標頭完全可被客戶端偽造(curl、Postman、瀏覽器擴充套件皆可自定義標頭)。因此:
class HttpRequest {
public static function isAjax(): bool {
return (isset($_SERVER['HTTP_X_REQUESTED_WITH'])
&& strcasecmp($_SERVER['HTTP_X_REQUESTED_WITH'], 'XMLHttpRequest') === 0);
}
public static function wantsJson(): bool {
return self::isAjax()
|| (isset($_SERVER['HTTP_ACCEPT'])
&& strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false);
}
}
// 控制器中使用
if (HttpRequest::wantsJson()) {
return response()->json($data);
}
return view('page', compact('data'));
檢測 HTTP_X_REQUESTED_WITH 是識別 AJAX 請求的行業慣例,實現簡單、兼容性好。但務必牢記:**它不是安全機制**,僅供「禮貌性」區分請求類型。安全防護請另行實施 CSRF Token、SameSite 等標準方案。