当我从终端运行curl -I http://api.stackoverflow.com/1.1/badges
时,会显示以下标题:
HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 42804
Content-Type: application/json; charset=utf-8
Content-Encoding: gzip
X-AspNetMvc-Version: 4.0
X-RateLimit-Max: 300
X-RateLimit-Current: 297
X-AspNet-Version: 4.0.30319
Set-Cookie: .ASPXBrowserOverride=; expires=Mon, 08-Oct-2012 04:29:28 GMT; path=/
Date: Tue, 09 Oct 2012 04:29:27 GMT
然而,当我通过PHP运行相同的cURL请求时,我得到了这个:
Array
(
[url] => http://api.stackoverflow.com/1.1/badges?10102
[content_type] => application/json; charset=utf-8
[http_code] => 200
[header_size] => 277
[request_size] => 85
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 0.168343
[namelookup_time] => 0.023417
[connect_time] => 0.046293
[pretransfer_time] => 0.046365
[size_upload] => 0
[size_download] => 42804
[speed_download] => 254266
[speed_upload] => 0
[download_content_length] => 42804
[upload_content_length] => 0
[starttransfer_time] => 0.097563
[redirect_time] => 0
[certinfo] => Array
(
)
[redirect_url] =>
)
对我来说最重要的区别是,当通过PHP运行时,我没有得到Content-Encoding
标题,如果没有标题,我不知道内容是否需要gzip膨胀。
有没有办法获取Content-Encoding
标头,或者以其他方式检查gzip压缩?
答案 0 :(得分:4)
返回的getinfo数组中没有header_response
和accept-encoding
。我认为getinfo上的CURLINFO_HEADER_OUT
会给出响应头,但只给出了请求头。
但是您可以使用CURLOPT_HEADER
选项设置为true来获取原始标头。所以我建议你做一些不太自然的事情:
$curl = curl_init();
$opts = array (
CURLOPT_URL => 'http://api.stackoverflow.com/1.1/badges',
CURLOPT_TIMEOUT => 120,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_ENCODING => 'gzip',
CURLOPT_HEADER => true,
);
curl_setopt_array($curl, $opts);
$return = curl_exec($curl);
list($rawHeader, $response) = explode("\r\n\r\n", $return, 2);
$cutHeaders = explode("\r\n", $rawHeader);
$headers = array();
foreach ($cutHeaders as $row)
{
$cutRow = explode(":", $row, 2);
$headers[$cutRow[0]] = trim($cutRow[1]);
}
echo $headers['Content-Encoding']; // gzip
答案 1 :(得分:3)
如果您将CURLOPT_HEADER
设置为true
,则curl会将标题返回到正文旁边。如果您只对标题感兴趣,可以将CURLOPT_NOBODY
设置为true
并且不返回正文(在命令行上模拟-I
标志)。
此示例仅设置CURLOPT_HEADER
,读取Content-Encoding
标头(如果已设置)并解压缩正文:
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "http://api.stackoverflow.com/1.1/badges");
curl_setopt($curl, CURLOPT_HEADER, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($curl);
curl_close($curl);
list($header, $body) = explode("\r\n\r\n", $response, 2);
if(preg_match('@Content-Encoding:\s+(\w+)@i', $header, $match)) {
switch (strtolower($match[1])) {
case 'gzip':
$body = gzdecode($body);
break;
case 'compress':
$body = gzuncompress($body);
break;
case 'deflate':
$body = gzdeflate($body);
break;
}
}
echo $header;
echo $body;
免责声明:您的PHP版本可能无法使用gzdecode
。我用PHP 5.4.4进行了测试,但它确实有效。
你也可以安装HTTP_Request2
- PEAR包为你做这件事(你可以轻松访问没有HTTP头解析的头文件):
include 'HTTP/Request2.php';
$request = new HTTP_Request2('http://api.stackoverflow.com/1.1/badges',
HTTP_Request2::METHOD_GET);
$response = $request->send();
echo $response->getBody();