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 相关文章推荐
一个取得文件扩展名的函数
Oct 09 PHP
PHP新手上路(二)
Oct 09 PHP
PHP6 先修班 JSON实例代码
Aug 23 PHP
php购物车实现代码
Oct 10 PHP
php cURL和Rolling cURL并发方式比较
Oct 30 PHP
php 中文字符串首字母的获取函数分享
Nov 04 PHP
php上传图片存入数据库示例分享
Mar 11 PHP
PHP实现设计模式中的抽象工厂模式详解
Oct 11 PHP
php生成图片验证码的实例讲解
Aug 03 PHP
CodeIgniter配置之config.php用法实例分析
Jan 19 PHP
Yii框架函数简单用法分析
Sep 09 PHP
tp5框架前台无限极导航菜单类实现方法分析
Mar 29 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
浅析ThinkPHP中execute和query方法的区别
2014/06/13 PHP
php实现统计网站在线人数的方法
2015/05/12 PHP
PHP7正式版测试,性能惊艳!
2015/12/08 PHP
利用PHP将图片转换成base64编码的实现方法
2016/09/13 PHP
PHP 传输会话curl函数的实例详解
2017/09/12 PHP
基于jquery的页面划词搜索JS
2010/09/14 Javascript
Javascript中定义方法的另类写法(批量定义js对象的方法)
2011/02/25 Javascript
读jQuery之四(优雅的迭代)
2011/06/20 Javascript
JavaScript等比例缩放图片控制超出范围的图片
2013/08/06 Javascript
JS控制网页动态生成任意行列数表格的方法
2015/03/09 Javascript
javascript实现checkbox全选的代码
2015/04/30 Javascript
jQuery实现向下滑出的平滑下拉菜单效果
2015/08/21 Javascript
基于JavaScript短信验证码如何实现
2016/01/24 Javascript
node.js缺少mysql模块运行报错的解决方法
2016/11/13 Javascript
Bootstrap框架实现广告轮播效果
2016/11/28 Javascript
详解Vue 方法与事件处理器
2017/06/20 Javascript
JavaScript中重名的函数与对象示例详析
2017/09/28 Javascript
使用Typescript和ES模块发布Node模块的方法
2020/05/25 Javascript
[05:13]TI4 中国战队 机场出征!!
2014/07/07 DOTA
Python绑定方法与非绑定方法详解
2017/08/18 Python
Python父目录、子目录的相互调用方法
2019/02/16 Python
Python列表的切片实例讲解
2019/08/20 Python
SELENIUM自动化模拟键盘快捷键操作实现解析
2019/10/28 Python
Python pip配置国内源的方法
2020/02/14 Python
Python Mock模块原理及使用方法详解
2020/07/07 Python
Django 实现图片上传和下载功能
2020/12/31 Python
纯css3无js实现的Android Logo(有简单动画)
2013/01/21 HTML / CSS
英国的一家创新礼品和小工具零售商:Menkind
2019/08/24 全球购物
优秀毕业生求职信
2014/06/05 职场文书
村主任群众路线教育实践活动个人对照检查材料思想汇报
2014/10/01 职场文书
2014年污水处理厂工作总结
2014/12/19 职场文书
美术教师个人总结
2015/02/06 职场文书
2015年设计师个人工作总结
2015/04/25 职场文书
乔布斯辞职信(中英文对照)
2015/05/12 职场文书
TensorFlow中tf.batch_matmul()的用法
2021/06/02 Python
HTML页面点击按钮关闭页面的多种方式
2022/12/24 HTML / CSS