codeigniter 3 中 $this->input->is_ajax_request() 通过检测 x-requested-with: xmlhttprequest 请求头判断 ajax 请求,但 axios、fetch 等现代库默认不发送该头,且 nginx/cdn 可能剥离它;推荐改用 $this->input->server('http_x_requested_with') 小写比对,或结合 accept: application/json 辅助判断。

如何用 $this->input->is_ajax_request() 判断 AJAX 请求
CodeIgniter 3 原生提供 $this->input->is_ajax_request() 方法,它本质是检测请求头中是否存在 X-Requested-With: XMLHttpRequest。这个判断简单直接,但依赖前端主动设置该 header —— 很多现代 JS 库(如 Axios、Fetch)默认不加,导致该方法返回 false。
实操建议:
- 如果用 jQuery 发起 AJAX,默认带上
X-Requested-With,is_ajax_request()可靠 - 若用 Axios,需显式配置:
headers: { 'X-Requested-With': 'XMLHttpRequest' } - Fetch 完全不自动设该 header,必须手动加:
headers: { 'X-Requested-With': 'XMLHttpRequest' } - 该方法在 CI4 中已移除,CI4 需改用
$request->isAJAX()(底层仍检查同一 header)
手动检测请求头比 is_ajax_request() 更稳妥的写法
绕过框架封装,直接读取 header 是最可控的方式,尤其当无法控制前端行为时。注意:PHP-FPM 或 Nginx 可能重写或过滤部分 header,X-Requested-With 就常被代理层丢弃。
推荐写法(CI3/CI4 均适用):
// CI3 写法(在控制器中)
$header = $this->input->server('HTTP_X_REQUESTED_WITH');
if (strtolower($header) === 'xmlhttprequest') {
// 确认为 AJAX
}
// CI4 写法(使用 Request 对象)
if ($request->getHeaderLine('X-Requested-With') === 'XMLHttpRequest') {
// 确认为 AJAX
}
关键点:
- 用
HTTP_前缀 + 大写下划线转换读取 server 变量(如X-Requested-With→HTTP_X_REQUESTED_WITH) - Nginx 默认不透传带下划线的 header,需在配置中加:
underscores_in_headers on;,否则$_SERVER['HTTP_X_REQUESTED_WITH']为空 - 大小写不敏感比较更安全,避免前端首字母大写不一致(如
Xmlhttprequest)
用 Accept 头或 Content-Type 辅助判断是否为 API 调用
单纯依赖 X-Requested-With 在前后端分离场景下越来越不可靠。很多真实业务中,“是否 AJAX”其实等价于“是否期望 JSON 响应”,这时看 Accept 或 Content-Type 更有意义。
常见组合判断逻辑:
-
$this->input->get_request_header('Accept')包含application/json→ 视为 API 请求 -
$this->input->get_request_header('Content-Type')为application/json→ 通常是 Fetch/Axios 的 POST/PUT - 同时满足
Accept: application/json且请求方法为POST或GET→ 可安全返回 JSON 而非视图 - 注意:浏览器地址栏直接访问也会带
Accept: text/html,不能单靠 Accept 判定,需结合上下文
CI3 升级到 CI4 后请求类型检测的变化与坑
CI4 彻底重构了输入处理机制,$this->input 已废弃,所有请求信息通过 $request(CodeIgniter\HTTP\Request 实例)获取,且 isAJAX() 行为略有差异。
迁移要点:
- CI4 的
$request->isAJAX()仍检查X-Requested-With,但会忽略 header 值大小写,并兼容空格(如" XMLHttpRequest ") - CI4 默认启用
strict_route,若路由未显式允许OPTIONS,预检请求(CORS)会失败,导致后续 AJAX 请求卡住 —— 这常被误判为“AJAX 检测失效” - CI4 中
$request->getIPAddress()和$request->getUserAgent()返回对象而非字符串,不要直接 echo - 若项目混用 CI3 和 CI4 的中间件逻辑,注意
is_ajax_request()在 CI3 中对 CLI 请求也返回 false,而 CI4 的isAJAX()在 CLI 下抛异常,需提前 guard
真正容易被忽略的是:Nginx 或 CDN 层可能静默剥离自定义 header,哪怕代码写对了,线上仍检测不到 X-Requested-With —— 遇到“本地 OK、线上失效”,第一反应不该是改 PHP 逻辑,而是查 header 是否抵达 PHP 进程。











