如何防止index.php中jQuery调用的refreshdata.php被直接执行
禁止直接访问refreshdata.php的实现方法
注:所有前端发起的HTTP请求都可以被抓包伪造,不存在完全无法绕过的拦截方案,以下方法可以拦截几乎所有普通用户直接输入地址访问的行为
方法1:校验AJAX默认请求头(配置最简单)
jQuery封装的AJAX请求(包括你用的.load()方法),默认会自动携带X-Requested-With: XMLHttpRequest请求头,用户直接在浏览器地址栏访问文件时不会携带这个头,你只需要在refreshdata.php文件最开头加入如下校验代码即可,不需要修改现有前端JS代码:
<?php // 放在refreshdata.php所有业务代码之前 if (empty($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest') { http_response_code(403); exit('禁止直接访问该文件'); } // 下方写你原本的refreshdata.php业务逻辑
方法2:令牌+来源校验(提高伪造门槛)
如果需要更高的拦截强度,可以叠加令牌校验和来源校验,进一步降低被绕过的概率:
- 首先在
index.php最顶部开启session,生成随机校验令牌:
<?php // index.php最开头加入 session_start(); // 生成16位随机令牌 $_SESSION['refresh_token'] = bin2hex(random_bytes(16)); ?>
- 修改你现有的jQuery轮询代码,请求时携带令牌:
<script type="text/javascript"> $(document).ready(function(){ refreshTable(); }); function refreshTable(){ $('#tableHolder').load('refreshdata.php', { req_token: "<?php echo $_SESSION['refresh_token']; ?>" }, function(){ setTimeout(refreshTable, 10000); }); } </script>
- 在
refreshdata.php开头加入多层校验逻辑:
<?php // refreshdata.php所有业务代码前加入 session_start(); // 校验1:必须是AJAX请求 if (empty($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest') { http_response_code(403); exit('非法访问'); } // 校验2:请求来源必须是本站 if (empty($_SERVER['HTTP_REFERER']) || parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) !== $_SERVER['HTTP_HOST']) { http_response_code(403); exit('非法请求来源'); } // 校验3:令牌必须匹配 if (empty($_POST['req_token']) || $_POST['req_token'] !== $_SESSION['refresh_token']) { http_response_code(403); exit('请求校验失败'); } // 下方写你原本的refreshdata.php业务逻辑
方法3:Web服务器层直接拦截(无需修改PHP代码)
如果你有服务器配置权限,也可以直接在Web服务层面加规则拦截,执行效率更高:
- Nginx规则(放在站点配置里):
location = /refreshdata.php { # 拦截不带AJAX标识头的请求 if ($http_x_requested_with != "XMLHttpRequest") { return 403; } # 保留你原本的PHP解析配置即可 include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }
- Apache规则(放在站点根目录的
.htaccess文件里):
<Files "refreshdata.php"> RewriteEngine On RewriteCond %{HTTP:X-Requested-With} !^XMLHttpRequest$ RewriteRule .* - [F,L] </Files>
补充:如果你的业务对安全性要求极高,不要只依赖以上基础校验,可以额外加接口签名、访问频率限制等防护,不过应对普通用户直接访问的场景,以上方案完全够用。
内容的提问来源于stack exchange,提问作者Alex B.
相关产品推荐
相关产品推荐

