我有一个使用cURL(最新版本)连接到安全网关进行付款的网站。
问题是cURL总是返回0长度内容。我只收到标题。只有当我设置cURL返回标题时。我有以下标志。
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_URL, $gatewayURI);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_POST, 1);
返回的标头是
HTTP/1.1 100 Continue
HTTP/1.1 200 OK
Date: Tue, 25 Nov 2008 01:08:34 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Content-Length: 0
Content-Type: text/html
Set-Cookie: ASPSESSIONIDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; path=/
Cache-control: private
我也尝试了不同的网站cURL,他们返回的内容很好。我认为问题可能与https连接有关。
我和公司谈过,他们没有帮助。
是否有其他人遇到此错误并知道解决方法?我应该抛弃cURL并尝试使用fsockopen()
吗?
谢谢。 :)
答案 0 :(得分:98)
我今天遇到了同样的问题。 Curl附带了一个过时的文件来验证来自。
的HTTPS证书从以下网址获取新内容:
http://curl.haxx.se/ca/cacert.pem
将其保存到您网站上的某个目录
并添加
curl_setopt ($curl_ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem");
对每个请求: - )
IGNORE关于禁用CURLOPT_VERIFYPEER和CURLOPT_VERIFYHOST的任何愚蠢的评论!!这使得你的代码在中间攻击时容易受到攻击!
2016年12月编辑:
使用下面提到的Jasen方法正确解决这个问题。
将curl.cainfo=/etc/ssl/certs/ca-certificates.crt
添加到php.ini
2017年10月编辑:
现在有一个作曲家软件包可以帮助您管理ca证书,这样如果您的cacert.pem由于撤销证书而过时,您就不会受到攻击。
https://github.com/paragonie/certainty - > composer require paragonie/certainty:dev-master
答案 1 :(得分:33)
您还应该尝试检查curl_error()中的错误消息。在每个curl_ *函数之后,您可能需要执行此操作。
答案 2 :(得分:28)
注意:这绝对不是生产用途。如果您想快速调试,这可能很有用。否则,请使用@ SchizoDuckie的答案。
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
只需添加它们即可。有用。
答案 3 :(得分:6)
刚出现一个非常相似的问题并通过添加
解决了这个问题curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
显然我正在抓取的网站重定向到另一个位置,并且php-curl默认不遵循重定向。
答案 4 :(得分:4)
我遇到了这样的情况:( Windows上的PHP 5.4.16)
curl_setopt($ch, CURLOPT_SSLVERSION, 3);
答案 5 :(得分:3)
每当我使用PHP / Curl测试时,我首先从命令行尝试,找出有效的方法,然后将我的选项移植到PHP。
答案 6 :(得分:2)
有时您必须将Curl证书升级到最新版本,以免出现https错误。
答案 7 :(得分:1)
我使用file_get_contents
使用stream_create_context
并且工作正常:
$postdataStr = http_build_query($postdataArr);
$context_options = array (
'http' => array ( <blink> // this will allways be http!!!</blink>
'method' => 'POST',
'header'=> "Content-type: application/x-www-form-urlencoded\r\n"
. "Content-Length: " . strlen($postdataArr) . "\r\n"
. "Cookie: " . $cookies."\r\n"
'content' => $postdataStr
)
);
$context = stream_context_create($context_options);
$HTTPSReq = file_get_contents('https://www.example.com/', false, $context);
答案 8 :(得分:0)
您的网络托管公司可能存在问题,您正在测试网关的安全通信,他们可能不会允许您这样做。
也可能在连接到远程主机之前必须提供用户名密码。
或您的IP可能需要位于远程服务器的已批准IP列表中,以便启动通信。
答案 9 :(得分:0)
我在最近的应用程序项目中发现了这个错误。我写的是从命令行或浏览器窗口运行,因此我使用服务器检测来获取我要求的文档的相对URL。问题是,该站点是https,每次我尝试访问http://(same服务器时),cURL都帮助将其更改为https。
这可以在浏览器中正常工作,但是从命令行开始,即使将两个verify设置为false,我也会收到SSL错误。我必须做的是,
1)检查$ _SERVER ['HTTP_HOST']。如果存在,请使用($ _SERVER ['HTTPS']?“https://”:“http://”)。$ _ SERVER ['HTTP_HOST']
2)检查$ _SERVER ['COMPUTERNAME'],如果它与生产服务器匹配,请提供https URL。 ( “https://(servername)”)
3)如果两个条件都没有通过,则意味着我在另一台服务器上运行命令行,并使用“http://localhost”。
现在,这有效,但这是一个黑客。此外,我从来没有弄清楚为什么在一台服务器上(https)cURL改变了我的URL,而在另一台服务器(也是https)上它只留下了我的URL。
怪异。
答案 10 :(得分:0)
使用https并避免安全问题的最佳方法是使用Firefox(或其他工具)并将证书下载到您的服务器。 This webpage helped me a lot,这些是对我有用的步骤:
1)在Firefox中打开您将与CURL一起使用的网址
2)在地址栏上点击padlock
&gt; more information
(FF版本可以有不同的菜单,只需找到它)。单击查看证书按钮&gt; Details
标签。
3)突出显示&#34;右&#34; Certificate hierarchy
中的证书。就我而言,它是三分之二,名为&#34; cPanel,Inc。Certification Authority&#34;。我刚刚通过&#34;试验和错误发现了正确的#34;方法
4)单击导出按钮。在我的情况下,工作的人是文件类型&#34; PEM with chains&#34; (再次通过反复试验法)。
5)然后在PHP脚本中添加:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, [PATH_TO_CRT_FILE]);
此外,我要说的是,我们必须注意这些步骤可能需要每年重做一次,或者更换或续订URL证书时。
答案 11 :(得分:-1)
您正在使用POST方法,但是您提供了一组数据吗? E.g。
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);