Может ли PHP cURL получить заголовки ответа и тело в одном запросе? - PullRequest
292 голосов
/ 08 февраля 2012

Есть ли способ получить заголовки и тело для запроса cURL, используя PHP?Я обнаружил, что эта опция:

curl_setopt($ch, CURLOPT_HEADER, true);

собирается вернуть тело плюс заголовки , но затем мне нужно проанализировать его, чтобы получить тело.Есть ли способ получить как более удобный (и безопасный) способ?

Обратите внимание, что для "одного запроса" я имею в виду избегать выдачи запроса HEAD до GET / POST.

Ответы [ 13 ]

0 голосов
/ 15 июля 2016

Проблема со многими ответами здесь заключается в том, что "\r\n\r\n" может на законных основаниях появляться в теле html, поэтому вы не можете быть уверены, что правильно разбиваете заголовки.

Кажется, что единственный способ хранить заголовки отдельно при одном вызове curl_exec - это использовать обратный вызов, как предложено выше в https://stackoverflow.com/a/25118032/3326494

А затем, чтобы (надежно) получить только тело запроса, вам необходимо передать значение заголовка Content-Length в substr() как отрицательное начальное значение.

0 голосов
/ 24 февраля 2015

Если вам не нужно использовать curl;

$body = file_get_contents('http://example.com');
var_export($http_response_header);
var_export($body);

Какие выходы

array (
  0 => 'HTTP/1.0 200 OK',
  1 => 'Accept-Ranges: bytes',
  2 => 'Cache-Control: max-age=604800',
  3 => 'Content-Type: text/html',
  4 => 'Date: Tue, 24 Feb 2015 20:37:13 GMT',
  5 => 'Etag: "359670651"',
  6 => 'Expires: Tue, 03 Mar 2015 20:37:13 GMT',
  7 => 'Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT',
  8 => 'Server: ECS (cpm/F9D5)',
  9 => 'X-Cache: HIT',
  10 => 'x-ec-custom-error: 1',
  11 => 'Content-Length: 1270',
  12 => 'Connection: close',
)'<!doctype html>
<html>
<head>
    <title>Example Domain</title>...

См. http://php.net/manual/en/reserved.variables.httpresponseheader.php

0 голосов
/ 12 ноября 2014

Вернуть заголовки ответа с опорным параметром:

<?php
$data=array('device_token'=>'5641c5b10751c49c07ceb4',
            'content'=>'测试测试test'
           );
$rtn=curl_to_host('POST', 'http://test.com/send_by_device_token', array(), $data, $resp_headers);
echo $rtn;
var_export($resp_headers);

function curl_to_host($method, $url, $headers, $data, &$resp_headers)
         {$ch=curl_init($url);
          curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $GLOBALS['POST_TO_HOST.LINE_TIMEOUT']?$GLOBALS['POST_TO_HOST.LINE_TIMEOUT']:5);
          curl_setopt($ch, CURLOPT_TIMEOUT, $GLOBALS['POST_TO_HOST.TOTAL_TIMEOUT']?$GLOBALS['POST_TO_HOST.TOTAL_TIMEOUT']:20);
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
          curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
          curl_setopt($ch, CURLOPT_HEADER, 1);

          if ($method=='POST')
             {curl_setopt($ch, CURLOPT_POST, true);
              curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
             }
          foreach ($headers as $k=>$v)
                  {$headers[$k]=str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $k)))).': '.$v;
                  }
          curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
          $rtn=curl_exec($ch);
          curl_close($ch);

          $rtn=explode("\r\n\r\nHTTP/", $rtn, 2);    //to deal with "HTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 200 OK...\r\n\r\n..." header
          $rtn=(count($rtn)>1 ? 'HTTP/' : '').array_pop($rtn);
          list($str_resp_headers, $rtn)=explode("\r\n\r\n", $rtn, 2);

          $str_resp_headers=explode("\r\n", $str_resp_headers);
          array_shift($str_resp_headers);    //get rid of "HTTP/1.1 200 OK"
          $resp_headers=array();
          foreach ($str_resp_headers as $k=>$v)
                  {$v=explode(': ', $v, 2);
                   $resp_headers[$v[0]]=$v[1];
                  }

          return $rtn;
         }
?>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...