如何用PHP确定发起AJAX请求的源文件(客户端不可篡改数据)
这个问题我之前也碰到过,其实是HTTP协议的特性导致的:ajax.js是作为index.php页面的资源被加载运行的,当它发起AJAX请求时,浏览器会把承载它的页面URL(也就是index.php)设为请求的Referer头,而不是JS文件本身。所以靠$_SERVER['HTTP_REFERER']根本没法区分是页面直接发起的请求,还是页面里的JS发起的。
可行的解决方案
遗憾的是,HTTP协议本身并没有提供能直接标识发起请求的JS文件的原生、不可篡改的字段——毕竟客户端发送的任何数据理论上都能被篡改。但咱们可以通过约定自定义标识+辅助验证的方式来实现需求,同时尽量提升可靠性:
1. 主动添加自定义请求标识
在ajax.js发起AJAX请求时,手动加一个自定义的请求头或者URL参数,用来标记请求来源:
原生JS示例
const xhr = new XMLHttpRequest(); xhr.open('POST', '/ajax.php', true); // 添加自定义请求头 xhr.setRequestHeader('X-Request-Source', 'ajax.js'); // 发送请求 xhr.send();
jQuery示例
$.ajax({ url: '/ajax.php', method: 'POST', // 自定义请求头 headers: { 'X-Request-Source': 'ajax.js' }, success: function(res) { // 处理响应 } });
然后在ajax.php里读取这个标识:
// 获取自定义请求头(注意HTTP头会自动转为大写,前缀加HTTP_) $source = $_SERVER['HTTP_X_REQUEST_SOURCE'] ?? 'unknown'; if ($source === 'ajax.js') { // 确认是ajax.js发起的请求 // 执行对应逻辑 } else { // 其他来源的请求,做相应处理 }
2. 提升标识的可信度(可选)
如果担心有人恶意篡改这个标识,可以配合以下方式加固:
- CSRF令牌验证:在
index.php页面生成唯一的CSRF令牌,存在页面的隐藏字段或者全局变量里,ajax.js发起请求时带上这个令牌,ajax.php验证令牌的有效性。这样就算标识被篡改,没有合法的令牌也无法通过校验。 - HMAC签名:对请求参数和自定义标识一起用后端持有的密钥生成签名,
ajax.js把签名随请求发送,ajax.php重新计算签名并比对。不过这种方式需要在前端处理签名,密钥有泄露风险,适合对安全性要求较高的场景。
关键提醒
一定要明确:不存在完全不可篡改的客户端请求数据,攻击者可以用Postman、浏览器开发者工具这类工具伪造任何请求头或参数。上面的方案是在“信任自身前端代码”的前提下,区分请求来源的实用方法。如果是做权限控制,绝对不能只依赖这个标识,必须配合后端的身份验证和权限校验。
内容的提问来源于stack exchange,提问作者DMVerfurth
相关产品推荐
相关产品推荐

