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 相关文章推荐
windows下升级PHP到5.3.3的过程及注意事项
Oct 12 PHP
PHP函数之error_reporting(E_ALL ^ E_NOTICE)详细说明
Jul 01 PHP
php一次性删除前台checkbox多选内容的方法
Sep 22 PHP
div li的多行多列 无刷新分页示例代码
Oct 16 PHP
PHP实现简单爬虫的方法
Jul 29 PHP
php实现的数字验证码及数字运算验证码
Jul 30 PHP
基于php实现七牛抓取远程图片
Dec 01 PHP
利用ajax和PHP实现简单的流程管理
Mar 23 PHP
PHP基于Redis消息队列实现发布微博的方法
May 03 PHP
PHP+jQuery实现滚屏无刷新动态加载数据功能详解
May 04 PHP
Yii框架getter与setter方法功能与用法分析
Oct 22 PHP
php 函数中静态变量使用的问题实例分析
Mar 05 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生成随机数或者字符串的代码
2008/09/05 PHP
php at(@)符号的用法简介
2009/07/11 PHP
php ob_flush,flush在ie中缓冲无效的解决方法
2010/05/09 PHP
PHP聊天室简单实现方法详解
2018/12/08 PHP
jQuery 锚点跳转滚动条平滑滚动一句话代码
2010/04/30 Javascript
如何使用jquery控制CSS样式,并且取消Css样式(如背景色,有实例)
2013/07/09 Javascript
JS和jquery获取各种屏幕的宽度和高度的代码
2013/08/02 Javascript
jQuery中选择器小问题(新人难免遇到)
2014/03/31 Javascript
Javascript基础教程之关键字和保留字汇总
2015/01/18 Javascript
JavaScript设置表单上传时文件个数的方法
2015/08/11 Javascript
Bootstrap3 input输入框插入glyphicon图标的方法
2016/05/16 Javascript
完美的js图片轮换效果
2017/02/05 Javascript
用js将long型数据转换成date型或datetime型的实例
2017/07/03 Javascript
jQuery.extend 与 jQuery.fn.extend的用法及区别实例分析
2018/07/25 jQuery
vue-router实现嵌套路由的讲解
2019/01/19 Javascript
《javascript设计模式》学习笔记四:Javascript面向对象程序设计链式调用实例分析
2020/04/07 Javascript
vue+element table表格实现动态列筛选的示例代码
2021/01/14 Vue.js
原生js实现自定义滚动条组件
2021/01/20 Javascript
[04:56]经典回顾:前Ehome 与 前LGD
2015/02/26 DOTA
Python 命令行非阻塞输入的小例子
2013/09/27 Python
Django中传递参数到URLconf的视图函数中的方法
2015/07/18 Python
Python 功能和特点(新手必学)
2015/12/30 Python
Pytorch 图像变换函数集合小结
2021/02/01 Python
HTML5实现视频弹幕功能
2019/08/09 HTML / CSS
加州风格的游泳和沙滩装品牌:Cupshe
2019/06/10 全球购物
J2SDK1.5与J2SDK5.0有什么区别
2012/09/19 面试题
校园报刊亭创业计划书
2014/01/02 职场文书
理工类毕业自我鉴定
2014/02/20 职场文书
化工见习报告范文
2014/10/31 职场文书
倡议书作文
2015/01/19 职场文书
农业项目合作意向书
2015/05/08 职场文书
某药房的新员工入职告知书!
2019/07/15 职场文书
工作计划范文之财务管理
2019/08/09 职场文书
python实现Thrift服务端的方法
2021/04/20 Python
Python数据分析之绘图和可视化详解
2021/06/02 Python
SpringBoot中获取profile的方法详解
2022/04/08 Java/Android