PHP Curl请求返回401未授权,但手动访问正常问题排查
我之前碰到过一模一样的场景:手动打开图片完全正常,但用PHP Curl请求就返回401。改User-Agent没用的话,大概率是其他请求参数和浏览器不一致导致的,给你几个排查方向:
Cookie缺失是最常见的原因
手动访问时,浏览器会自动带上之前登录生成的会话Cookie(比如SESSIONID这类),但Curl默认是“干净”的请求,不会携带任何Cookie。你可以先打开浏览器的开发者工具(F12),在「网络」面板里找到访问图片的请求,复制里面的Cookie字段,然后在Curl里加上:$curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_RETURNTRANSFER => 1, CURLOPT_URL => 'http://example.com/user1.jpg', CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0', CURLOPT_COOKIE => 'SESSIONID=xxx; other_cookie=yyy' // 替换成你复制的Cookie内容 )); $resp = curl_exec($curl); echo $resp; curl_close($curl);如果是需要先登录才能获取图片,你还可以用Curl先模拟登录请求,把Cookie保存到文件里,再请求图片(用
CURLOPT_COOKIEJAR和CURLOPT_COOKIEFILE参数)。服务器检查Referer字段
有些网站会限制图片的请求来源,只有从本站页面发起的请求才允许访问。手动访问时浏览器会自动带上当前页面的Referer,但Curl默认没有这个字段。你可以添加Referer设置:curl_setopt($curl, CURLOPT_REFERER, 'http://example.com/'); // 替换成图片所在的页面URL会话和IP绑定
部分网站会把登录会话和你的客户端IP绑定,而本地Web服务器的IP可能和你手动访问的IP不一样(比如服务器是内网IP,或者用了代理),导致会话失效被拒绝。这种情况你可以试试让Curl使用和手动访问相同的IP,或者确认网站是否有IP绑定的限制。缺失其他浏览器请求头
浏览器发送请求时会带上很多头部字段(比如Accept、Accept-Language、Connection等),Curl默认只发送少数几个。你可以把浏览器里的请求头全部复制过来,用CURLOPT_HTTPHEADER添加到Curl里:curl_setopt($curl, CURLOPT_HTTPHEADER, array( 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language: zh-CN,zh;q=0.8,en;q=0.5', 'Connection: keep-alive' ));HTTP基础认证(Basic Auth)
虽然手动访问没弹出登录框,但可能浏览器已经保存了认证信息。你可以尝试添加用户名和密码:curl_setopt($curl, CURLOPT_USERPWD, 'username:password');
最有效的排查方法就是:用浏览器开发者工具对比手动请求和Curl请求的所有参数(Cookie、请求头、IP等),把Curl的请求完全模拟成浏览器的样子,基本就能解决问题。
内容的提问来源于stack exchange,提问作者catalin

