PHP cURL开启CURLOPT_FOLLOWLOCATION仍报302访问被拒如何解决
核心原因
- 你遇到的问题和cURL不跟随重定向无关,也和PHP配置无关。老资料里提到的
safe_mode、open_basedir导致CURLOPT_FOLLOWLOCATION失效的问题,仅存在于PHP 5.3及更早的过时版本,PHP 8.1已经完全移除了相关限制,这部分排查方向从一开始就是错的。 - 你拿到的
302 Access denied响应是Macys站点的WAF(Web应用防火墙)返回的拦截跳转,不是站点正常的业务重定向。cURL实际上已经按照你的配置执行了重定向跟随,只是跟随到拦截地址后直接返回了“无访问权限”的提示内容,才会让你误以为重定向功能没生效。 - 你提到的
enable_dl配置和当前问题完全无关,这个选项的作用是控制是否允许运行时动态加载PHP扩展,和cURL的请求逻辑、重定向逻辑没有任何关联,修改这个配置不会对结果产生任何影响。 - 拦截的核心原因是你的请求特征和真实浏览器差异过大,WAF识别到这是自动化脚本发出的请求,直接触发了拦截规则。你当前的代码只配置了User-Agent,缺少了真实浏览器会携带的大量请求头、Cookie上下文,非常容易被识别为爬虫。
修正方案
对你现有代码做如下调整即可:
- 补充真实浏览器会携带的常规HTTP头,包括Accept、Accept-Language、Sec-Fetch系列头等,和你声明的Firefox 100浏览器的请求特征对齐
- 开启Cookie自动存储与携带,WAF的拦截校验通常依赖Cookie上下文,无Cookie的请求会被直接判定为爬虫
- 保持默认SSL校验配置不要关闭,部分站点会对SSL握手异常的请求直接拦截
- 开启自动响应解压,匹配真实浏览器的压缩编码支持特征
修正后的可运行代码如下:
$url = 'https://www.macys.com'; $ch = curl_init(); // 基础请求配置 curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_MAXREDIRS, 10); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0'); // SSL配置 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // Cookie配置,使用系统临时目录存储Cookie文件 $cookiePath = tempnam(sys_get_temp_dir(), 'macys_curl_'); curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiePath); curl_setopt($ch, CURLOPT_COOKIEFILE, $cookiePath); // 补充浏览器标准请求头 curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8', 'Accept-Language: en-US,en;q=0.5', 'Accept-Encoding: gzip, deflate, br', 'Connection: keep-alive', 'Upgrade-Insecure-Requests: 1', 'Sec-Fetch-Dest: document', 'Sec-Fetch-Mode: navigate', 'Sec-Fetch-Site: none', 'Sec-Fetch-User: ?1' ]); // 自动处理gzip/br等压缩响应 curl_setopt($ch, CURLOPT_ENCODING, ''); $contents = curl_exec($ch); $curl_info = curl_getinfo($ch); curl_close($ch); print_r($curl_info); echo $contents;
补充说明:如果调整代码后仍然返回访问被拒,说明你当前使用的服务器IP已经被Macys的反爬系统标记为机房/代理IP,这种情况更换为正常住宅网络出口IP即可解决,和代码、PHP环境配置没有关系。
内容的提问来源于stack exchange,提问作者Tristan
相关产品推荐
相关产品推荐

