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 相关文章推荐
十天学会php之第六天
Oct 09 PHP
PHP stream_context_create()作用和用法分析
Mar 29 PHP
php学习之 数组声明
Jun 09 PHP
全新的PDO数据库操作类php版(仅适用Mysql)
Jul 22 PHP
php5.3 注意事项说明
Jul 01 PHP
PHP开源开发框架ZendFramework使用中常见问题说明及解决方案
Jun 12 PHP
php管理nginx虚拟主机shell脚本实例
Nov 19 PHP
PHP实现的比较完善的购物车类
Dec 02 PHP
php上传文件常见问题总结
Feb 03 PHP
PHP实现基于图的深度优先遍历输出1,2,3...n的全排列功能
Nov 10 PHP
PHP分享图片的生成方法
Apr 25 PHP
laravel5.6 框架操作数据 Eloquent ORM用法示例
Jan 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图片的二进制转换实现方法
2014/12/15 PHP
修改PHP脚本使WordPress拦截垃圾评论的方法示例
2015/12/10 PHP
php生成带logo二维码方法小结
2016/04/08 PHP
PHP检测数据类型的几种方法(总结)
2017/03/04 PHP
thinkphp框架表单数组实现图片批量上传功能示例
2020/04/04 PHP
javascript HTMLEncode HTMLDecode的完整实例(兼容ie和火狐)
2009/06/02 Javascript
jquery.hotkeys监听键盘按下事件keydown插件
2014/05/11 Javascript
使用jQuery判断IE浏览器版本的代码
2014/06/14 Javascript
JavaScript中的Primitive对象封装介绍
2014/12/31 Javascript
JavaScript事件委托用法分析
2015/01/24 Javascript
JavaScript DOM节点操作方法总结
2016/08/23 Javascript
微信小程序 摇一摇抽奖简单实例实现代码
2017/01/09 Javascript
三种方式实现瀑布流布局
2017/02/10 Javascript
vue.js获取数据库数据实例代码
2017/05/26 Javascript
VUE中v-model和v-for指令详解
2017/06/23 Javascript
ReactNative页面跳转Navigator实现的示例代码
2017/08/02 Javascript
vue+koa2实现session、token登陆状态验证的示例
2019/08/30 Javascript
js实现图片3D轮播效果
2019/09/21 Javascript
Node 模块原理与用法详解
2020/05/13 Javascript
JavaScript常用进制转换及位运算实例解析
2020/10/14 Javascript
node.js通过url读取文件
2020/10/16 Javascript
python实现获取Ip归属地等信息
2016/08/27 Python
python如何使用正则表达式的前向、后向搜索及前向搜索否定模式详解
2017/11/08 Python
python制作mysql数据迁移脚本
2019/01/01 Python
wxPython绘图模块wxPyPlot实现数据可视化
2019/11/19 Python
python求绝对值的三种方法小结
2019/12/04 Python
Django基于客户端下载文件实现方法
2020/04/21 Python
Python基于unittest实现测试用例执行
2020/11/25 Python
详解python使用金山词霸的翻译功能(调试工具断点的使用)
2021/01/07 Python
美国皮靴公司自1863年:The Frye Company
2016/11/30 全球购物
消防安全责任书范本
2014/04/15 职场文书
行政部经理助理岗位职责
2014/06/15 职场文书
2014年高中班主任工作总结
2014/11/08 职场文书
党风廉政建设个人总结
2015/03/06 职场文书
高中地理教学反思
2016/02/19 职场文书
python爬虫--selenium模块
2021/03/31 Python