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 数组遍历顺序理解
Sep 09 PHP
认识并使用PHP超级全局变量
Jan 26 PHP
php关于array_multisort多维数组排序的使用说明
Jan 04 PHP
php学习之简单计算器实现代码
Jun 09 PHP
如何在smarty中增加类似foreach的功能自动加载数据
Jun 26 PHP
PHP获取QQ达人QQ信息的方法
Mar 05 PHP
php图片添加文字水印实现代码
Mar 15 PHP
ThinkPHP框架搭建及常见问题(XAMPP安装失败、Apache/MySQL启动失败)
Apr 15 PHP
Json_decode 解析json字符串为NULL的解决方法(必看)
Feb 17 PHP
PHP中时间加减函数strtotime用法分析
Apr 26 PHP
php 删除指定文件夹的实例讲解
Jul 25 PHP
Laravel下生成验证码的类
Nov 15 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操作MySQL事务实例
2014/11/05 PHP
PHP实现的mysql主从数据库状态检测功能示例
2017/07/20 PHP
JQuery设置和去除disabled属性的5种方法总结
2013/05/16 Javascript
JS localStorage实现本地缓存的方法
2013/06/22 Javascript
JS小功能(onmouseover实现选择月份)实例代码
2013/11/28 Javascript
Jquery 动态生成表格示例代码
2013/12/24 Javascript
javascript性能优化之DOM交互操作实例分析
2015/12/12 Javascript
关于Bootstrap弹出框无法调用问题的解决办法
2016/03/10 Javascript
AngularJS基础 ng-repeat 指令简单示例
2016/08/03 Javascript
KnockoutJS 3.X API 第四章之数据控制流foreach绑定
2016/10/10 Javascript
JS实现字符串转驼峰格式的方法
2016/12/16 Javascript
如何清除IE10+ input X 文本框的叉叉和密码输入框的眼睛图标
2016/12/21 Javascript
vue引入js数字小键盘的实现代码
2018/05/14 Javascript
详解Vue中使用Echarts的两种方式
2018/07/03 Javascript
JavaScript数组基于交换的排序示例【冒泡排序】
2018/07/21 Javascript
微信网页授权并获取用户信息的方法
2018/07/30 Javascript
微信小程序实现留言板功能
2018/11/02 Javascript
详解Vue组件之间通信的七种方式
2019/04/14 Javascript
使用webpack和rollup打包组件库的方法
2021/02/25 Javascript
Django imgareaselect手动剪切头像实现方法
2015/05/26 Python
Python中几个比较常见的名词解释
2015/07/04 Python
python制作websocket服务器实例分享
2016/11/20 Python
Python队列的定义与使用方法示例
2017/06/24 Python
python GUI库图形界面开发之PyQt5树形结构控件QTreeWidget详细使用方法与实例
2020/03/02 Python
Python利用imshow制作自定义渐变填充柱状图(colorbar)
2020/12/10 Python
HTML5 Web Database 数据库的SQL语句的使用方法
2012/12/09 HTML / CSS
Argos官网:英国家喻户晓的百货零售连锁商
2017/04/03 全球购物
孤独星球出版物:Lonely Planet Publications
2018/03/17 全球购物
JMS中Topic和Queue有什么区别
2013/05/15 面试题
运动会广播稿150字
2014/02/19 职场文书
成龙洗发水广告词
2014/03/14 职场文书
个人评语大全
2014/05/04 职场文书
2015年小学教师培训工作总结
2015/07/21 职场文书
Python机器学习之逻辑回归
2021/05/11 Python
tensorboard 可视化之localhost:6006不显示的解决方案
2021/05/22 Python
关于的python五子棋的算法
2022/05/02 Python