直接用 request()->isAjax() 即可,ThinkPHP 5/6 内置方法兼容 X-Requested-With 头、GET/POST 中的 ajax 参数(由 VAR_AJAX_SUBMIT 控制),规避 fetch 不带头、CDN 过滤、WebView 异常等边界问题,语义清晰且性能无损耗。

直接用 request()->isAjax() 就行,这是 ThinkPHP 5 和 6 的标准做法,底层稳定、语义清晰、无需手动检测头信息。
为什么不用自己读 $_SERVER['HTTP_X_REQUESTED_WITH']
自己写判断逻辑容易漏掉边界情况:比如某些前端库(如原生 fetch)默认不带 X-Requested-With 头;部分 CDN 或反向代理会过滤或重写该 header;移动端 WebView 也可能不发送。ThinkPHP 的 isAjax() 内部做了兼容性兜底——它不仅检查 HTTP_X_REQUESTED_WITH,还会 fallback 到检测 $_GET['ajax'] 或 $_POST['ajax'](由配置项 VAR_AJAX_SUBMIT 控制),但前提是你要确保没显式关闭这个机制。
常见错误现象:
- 本地 jQuery AJAX 正常,上线后
isAjax()总返回false→ 很可能是 Nginx 或 Cloudflare 过滤了X-Requested-With - 用
fetch发请求,没手动加 header →isAjax()不生效
request()->isAjax() 在不同版本的调用差异
ThinkPHP 5 和 6 都支持该方法,但获取 request 对象的方式略有不同:
立即学习“PHP免费学习笔记(深入)”;
- TP5:可在控制器中直接调用
$this->request->isAjax(),或使用助手函数request()->isAjax() - TP6:推荐使用依赖注入或
think\Request门面,request()->isAjax()依然可用,但注意别在构造函数里提前调用(此时 request 尚未初始化) - TP3.x 不支持该写法,必须用全局常量
IS_AJAX或手写判断逻辑
性能影响几乎为零——isAjax() 是轻量级判断,不触发 IO 或数据库操作。
Postman 或 curl 模拟 Ajax 请求时怎么配
调试接口时,如果 isAjax() 返回 false,大概率是请求头缺失。你需要显式带上:
- Header:
X-Requested-With: XMLHttpRequest - Content-Type 建议设为
application/x-www-form-urlencoded(表单提交)或application/json(JSON 提交),但后者不影响isAjax()判断
curl 示例:
curl -X POST http://localhost/test \ -H "X-Requested-With: XMLHttpRequest" \ -d "name=test"
注意:不要依赖 $_GET['ajax']=1 这类参数来“假装”是 AJAX,这既不安全(可被任意 URL 构造绕过),也不符合 HTTP 协议语义。
真正容易被忽略的点是:框架内部对 X-Requested-With 的值做了 strtolower() 处理,但如果你在 Postman 或代码里写成 XMLHttpRequest(首字母大写)也没问题;而一旦写成 xmlhttprequest 全小写,反而可能因中间件误处理导致 header 被丢弃——所以统一用首字母大写的标准写法最稳妥。



















