PHP Curl出现403错误的解决办法


Posted in PHP onMay 29, 2014

自己用的小PHP应用,使用curl抓网页下来处理,为了穿墙方便,使用Privoxy作为代理,便于选择哪些网站使用proxy、哪些不用。但今天却遇到了奇怪的问题,访问google baidu这些网站居然都返回403错误,而访问其他的一些网站没事,如果设置为不使用proxy则都能正常访问。

难道google baidu就不让用proxy连接么?显然不可能,所以打开curl的信息输出(curl_setopt($this->mSh, CURLOPT_VERBOSE, 1);)看看,得到以下结果:

*   Trying 127.0.0.1... * connected
* Connected to 127.0.0.1 (127.0.0.1) port 8118 (#0)
* Establish HTTP proxy tunnel to www.baidu.com:80
> CONNECT www.baidu.com:80 HTTP/1.0
Host: www.baidu.com:80
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Proxy-Connection: Keep-Alive
< HTTP/1.0 403 Connection not allowable
< X-Hint: If you read this message interactively, then you know why this happens ,-)
< 
* The requested URL returned error: 403
* Received HTTP code 403 from proxy after CONNECT
* Closing connection #0
... Failed.

可以看到proxy服务器工作正常,的确是baidu返回了403错误,但原因肯定还在我这边。终于,从网上(1of2, 2of2)得到了点启发──我使用的是proxytunnel而非proxy。

在代码中,有这么一句:

 curl_setopt($this->mSh, CURLOPT_HTTPPROXYTUNNEL, true);
 curl_setopt($this->mSh, CURLOPT_PROXY, $phost);

php文档中没有详细说明,不过man curl中有详细解释,两者都是代理,proxytunnel(-p参数)允许其他协议通过http代理传输,而proxy(-x参数)则只能走http协议。所以我猜测,google baidu的服务器和curl的proxytunnel不和,所以返回403。

禁用掉上面2行代码的第一句后,curl访问恢复正常。

比较奇怪的是,几种操作系统下还不一样,一台MAC OSX就要显式的禁用proxytunnel才可以,curl版本:

$ curl --version
curl 7.16.3 (powerpc-apple-darwin9.0) libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3
Protocols: tftp ftp telnet dict ldap http file https ftps 
Features: GSS-Negotiate IPv6 Largefile NTLM SSL libz

而另外一台ubuntu则完全不受影响,怎么都能用,curl版本:
$ curl --version
curl 7.18.2 (i486-pc-linux-gnu) libcurl/7.18.2 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.10
Protocols: tftp ftp telnet dict ldap ldaps http file https ftps 
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz

MT主机上的centos也没事,curl版本:
$ curl --version
curl 7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
Protocols: tftp ftp telnet dict ldap http file https ftps 
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz

看来不完全是curl版本问题,MAC OSX的确与众不同啊。

还有一个原因也会导致curl返回403错误,如果设置了:

 curl_setopt($ch, CURLOPT_NOBODY, true);

则需要紧跟着设置:
 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

不然会因为http服务器不允许 HEAD 命令而返回403错误。参考:Trouble with a cURL request in PHP(http://forums.devshed.com/php-development-5/trouble-with-a-curl-request-in-php-445222.html)。MAC OSX上curl之所以特殊,也不排除是这种原因吧。
PHP 相关文章推荐
加速XP搜索功能堪比vista
Mar 22 PHP
CodeIgniter框架数据库事务处理的设计缺陷和解决方案
Jul 25 PHP
php使用cookie显示用户上次访问网站日期的方法
Jan 26 PHP
6个超实用的PHP代码片段
Aug 10 PHP
yii去掉必填项中星号的方法
Dec 28 PHP
PHP实现的进度条效果详解
May 03 PHP
PHP中读取文件的几个方法总结(推荐)
Jun 03 PHP
thinkphp框架实现删除和批量删除
Jun 29 PHP
PHP针对多用户实现更换头像功能
Sep 04 PHP
PHP实现防盗链的方法分析
Jul 25 PHP
ThinkPHP5.0框架控制器继承基类和自定义类示例
May 25 PHP
PHP如何将图片文件上传到另外一台服务器上
Aug 26 PHP
PHP的foreach中使用引用时需要注意的一个问题和解决方法
May 29 #PHP
神盾加密解密教程(一)PHP变量可用字符
May 28 #PHP
CI框架开发新浪微博登录接口源码完整版
May 28 #PHP
PHP+javascript制作带提示的验证码源码分享
May 28 #PHP
微信支付开发教程(一)微信支付URL配置
May 28 #PHP
php中$美元符号与Zen Coding冲突问题解决方法分享
May 28 #PHP
php轻松实现中英文混排字符串截取
May 28 #PHP
You might like
PHP中的cookie不用刷新就生效的方法
2012/02/04 PHP
10个实用的PHP正则表达式汇总
2014/10/23 PHP
PHP实现一个轻量级容器的方法
2019/01/28 PHP
使用js获取QueryString的方法小结
2010/02/28 Javascript
js prototype截取字符串函数
2010/04/01 Javascript
基于jquery 的一个progressbar widge
2010/10/29 Javascript
jQuery学习笔记之jQuery选择器的使用
2010/12/22 Javascript
基于jquery可配置循环左右滚动例子
2011/09/09 Javascript
jquery修改属性值实例代码(设置属性值)
2014/01/06 Javascript
jquery 插件实现多行文本框[textarea]自动高度
2015/03/04 Javascript
jQuery实现div随意拖动的实例代码(通用代码)
2016/01/28 Javascript
微信小程序 教程之WXSS
2016/10/18 Javascript
微信小程序3D轮播实现代码
2019/09/19 Javascript
Vue中用JSON实现刷新界面不影响倒计时
2020/10/26 Javascript
[02:20]DOTA2亚洲邀请赛 EHOME战队出场宣传片
2015/02/07 DOTA
python算法学习之桶排序算法实例(分块排序)
2013/12/18 Python
zbar解码二维码和条形码示例
2014/02/07 Python
Python Web框架Flask信号机制(signals)介绍
2015/01/01 Python
python实现txt文件格式转换为arff格式
2018/05/31 Python
神经网络相关之基础概念的讲解
2018/12/29 Python
Python实现统计英文文章词频的方法分析
2019/01/28 Python
解决python打不开文件(文件不存在)的问题
2019/02/18 Python
Django使用redis缓存服务器的实现代码示例
2019/04/28 Python
python实现在函数中修改变量值的方法
2019/07/16 Python
tensorflow实现二维平面模拟三维数据教程
2020/02/11 Python
利用Python脚本批量生成SQL语句
2020/03/04 Python
香港迪士尼乐园酒店预订:Hong Kong Disneyland Hotels
2017/05/02 全球购物
英国街头品牌:Bee Inspired Clothing
2018/02/12 全球购物
英国在线照明超市:Castlegate Lights
2019/10/30 全球购物
经典c++面试题三
2015/07/08 面试题
Java servlet面试题
2012/03/04 面试题
《乌鸦和狐狸》教学反思
2014/02/08 职场文书
单位单身证明样本
2014/10/11 职场文书
房屋质量投诉书
2015/07/02 职场文书
图书借阅制度范本
2015/08/06 职场文书
HTML5+CSS+JavaScript实现捉虫小游戏设计和实现
2021/10/16 HTML / CSS