如何准确判断 HTTP 请求是否为 AJAX 请求

来源:站长源码作者:台湾程序员头衔:程序员
导读:本期聚焦于台湾程序员创作的《如何准确判断 HTTP 请求是否为 AJAX 请求》,敬请观看详情。服务端在处理接口时经常需要区分请求来源是浏览器直接访问还是 AJAX 异步请求,判断错了可能导致返回格式不统一甚至引发安全问题。本文围绕 HTTP 请求头中 X-Requested-With 字段的判断方法展开,讲解 jQuery 等主流库自动携带该头的原理,演示 PHP、Node.js、Java 等语言的服务端识别代码,同时分析该请求头可被伪造的风险以及自定义请求头的替代方案,帮助你在实际项目中既准确又安全地识别 AJAX 请求。

在前后端分离还不流行的年代,同一个 URL 往往既要服务浏览器的普通访问,又要服务页面里发出的异步请求。服务端需要知道请求的类型,才能决定返回完整 HTML 页面还是返回 JSON 数据,或者对非法请求直接拦截。判断一个 HTTP 请求是否为 AJAX 请求,最常用的依据就是请求头中的 X-Requested-With 字段,但它的原理和局限性很多人并不清楚。本文从请求头原理、各语言实现和安全性三个角度,把这个问题彻底讲透。

如何准确判断 HTTP 请求是否为 AJAX 请求

X-Requested-With 请求头的原理

AJAX 请求和普通 HTTP 请求在传输层面没有任何区别,它们都是标准的 HTTP 报文。所谓判断 AJAX 请求,本质上只能依赖一些约定俗成的特征,其中最通用的就是 X-Requested-With 这个自定义请求头。当它的值为 XMLHttpRequest 时,服务端通常就认定这是一个 AJAX 异步请求。

这个约定最早由 Prototype 框架引入,后来被 jQuery 等主流库沿用至今。jQuery 的 ajax 方法默认会在每个请求头中加上这一行:

$.ajax({
  url: "/api/user",
  type: "GET",
  // setHeaders 里默认已包含 X-Requested-With: XMLHttpRequest
  success: function (data) {
    console.log(data);
  }
});

发送原生 XMLHttpRequest 请求时,框架不会自动带这个头,需要手动设置。fetch API 同样如此,这也是很多开发者误以为原生请求不是 AJAX 的原因。正确写法如下:

var xhr = new XMLHttpRequest();
xhr.open("GET", "/api/user");
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.send();

// fetch 写法
fetch("/api/user", {
  headers: {
    "X-Requested-With": "XMLHttpRequest"
  }
});

需要注意,带自定义头的请求会触发跨域预检请求(OPTIONS),这是使用该方案时一个容易被忽视的副作用。

各语言服务端的判断实现

服务端拿到请求后,读取请求头并做比较即可。下面给出几种常见语言的实现方式,核心逻辑完全一致:判断 X-Requested-With 的值是否等于 XMLHttpRequest

PHP 中框架一般会封装好方法,原生写法如下:

<?php
function isAjax()
{
    return isset($_SERVER["HTTP_X_REQUESTED_WITH"])
        && strtolower($_SERVER["HTTP_X_REQUESTED_WITH"]) === "xmlhttprequest";
}

if (isAjax()) {
    echo json_encode(["code" => 0, "data" => []]);
} else {
    // 非 AJAX 请求,返回完整页面或拒绝访问
    http_response_code(403);
    exit("Forbidden");
}

Node.js 的 Express 框架提供了 req.xhr 属性,其内部实现同样是比对请求头:

app.get("/api/user", function (req, res) {
  if (req.xhr) {
    res.json({ code: 0, data: {} });
  } else {
    res.status(403).send("Forbidden");
  }
});

Java Servlet 中需要自己读取请求头,建议统一忽略大小写:

public static boolean isAjax(HttpServletRequest request) {
    String header = request.getHeader("X-Requested-With");
    return "XMLHttpRequest".equalsIgnoreCase(header);
}

除了看请求头,还可以结合 Accept 头辅助判断。AJAX 请求通常期望 JSON 或 XML,Accept 头会包含 application/json 之类的值,而浏览器地址栏访问时 Accept 值以 text/html 开头。两种方式结合使用,判断会更可靠一些。

这种判断方式的局限与安全风险

必须明确一点:X-Requested-With 是一个普通的自定义请求头,客户端可以随意设置或删除。用 curl 模拟一个 AJAX 请求只需要一行命令:

curl -H "X-Requested-With: XMLHttpRequest" https://yourdomain.com/api/user

因此这种判断只能用来区分请求形式,绝不能当作身份认证或防刷手段。如果把它当作安全机制,攻击者可以轻易绕过。真正需要防护的接口,应该依靠登录态校验、Token 验证、签名机制和频率限制等手段。

另一个局限是并非所有前端代码都会带这个头。旧项目中手写的 XMLHttpRequest、某些第三方 SDK 发出的请求可能没有这个头,服务端如果只认它就会误判。更稳妥的做法是由团队约定统一的自定义头,比如 App-Client: web,并在封装请求函数时强制添加,从源头保证一致性。

总结一下:判断 AJAX 请求的可靠做法是检查 X-Requested-With 头,必要时结合 Accept 头交叉验证;同时在架构上尽量让接口与页面路由分离,一个接口只返回一种格式,这样对请求来源的判断就从安全依赖退化成了锦上添花的辅助手段,系统整体也会更加清晰健壮。

AJAX请求判断X-Requested-WithHTTP请求头修改时间:2026-09-14 21:34:30

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260914/56852.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。