¿Hay alguna forma de obtener los encabezados y el cuerpo para una solicitud cURL usando PHP? Encontré que esta opción:
curl_setopt($ch, CURLOPT_HEADER, true);
va a devolver el cuerpo más los encabezados , pero luego necesito analizarlo para obtener el cuerpo. ¿Hay alguna forma de obtener ambos de una manera más utilizable (y segura)?
Tenga en cuenta que para "solicitud única" me refiero a evitar emitir una solicitud HEAD antes de GET / POST.
Respuestas:
Una solución a esto se publicó en los comentarios de la documentación de PHP: http://www.php.net/manual/en/function.curl-exec.php#80442
Ejemplo de código:
Advertencia: como se señala en los comentarios a continuación, esto puede no ser confiable cuando se usa con servidores proxy o cuando se manejan ciertos tipos de redireccionamientos. La respuesta de @ Geoffrey puede manejar esto de manera más confiable.
fuente
list($header, $body) = explode("\r\n\r\n", $response, 2)
hacerlo, pero esto puede demorar un poco más, dependiendo del tamaño de su solicitud.list($header, $body) = explode("\r\n\r\n", $response, 2)
como única variante de trabajo100
(Continuar). Para este encabezado, puede ir con la opción de solicitud que define correctamente:curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
deshabilitando el envío de esta respuesta de encabezado. En cuanto a302
, esto no debería suceder, porque el encabezado 302 es redirigido, no espera cuerpo, sin embargo, lo sé, a veces los servidores envían algún cuerpo con302
respuesta, pero de todos modos los navegadores lo ignorarán, hasta ahora, ¿por qué curl debería manejar esto? )CURLOPT_VERBOSE
está destinado a generar información de procesoSTDERR
(puede molestar en CLI) y para el problema discutido es inútil.Muchas de las otras soluciones que ofrece este hilo no lo están haciendo correctamente.
\r\n\r\n
no es confiable cuandoCURLOPT_FOLLOWLOCATION
está encendido o cuando el servidor responde con un código 100.\n
para nuevas líneas.CURLINFO_HEADER_SIZE
tampoco es siempre confiable, especialmente cuando se usan proxies o en algunos de los mismos escenarios de redireccionamiento.El método más correcto es usar
CURLOPT_HEADERFUNCTION
.Aquí hay un método muy limpio para realizar esto usando cierres de PHP. También convierte todos los encabezados a minúsculas para un manejo consistente en servidores y versiones HTTP.
Esta versión retendrá encabezados duplicados
Esto cumple con RFC822 y RFC2616, por favor no sugiera ediciones para hacer uso de las
mb_
funciones de cadena, ¡es incorrecto!fuente
$headers = [];
válido el php?Curl tiene una opción integrada para esto, llamada CURLOPT_HEADERFUNCTION. El valor de esta opción debe ser el nombre de una función de devolución de llamada. Curl pasará el encabezado (¡y solo el encabezado!) A esta función de devolución de llamada, línea por línea (por lo que se llamará a la función para cada línea de encabezado, comenzando desde la parte superior de la sección del encabezado). Su función de devolución de llamada puede hacer cualquier cosa con ella (y debe devolver el número de bytes de la línea dada). Aquí hay un código de trabajo probado:
Lo anterior funciona con todo, diferentes protocolos y proxys también, y no necesita preocuparse por el tamaño del encabezado, o establecer muchas opciones de rizo diferentes.
PD: para manejar las líneas de encabezado con un método de objeto, haga esto:
fuente
¿es esto lo que estás buscando?
fuente
A server that does not understand or is unable to comply with any of the expectation values in the Expect field of a request MUST respond with appropriate error status. The server MUST respond with a 417 (Expectation Failed) status if any of the expectations cannot be met or, if there are other problems with the request, some other 4xx status.
100
comentario en respuesta "correcta" .Solo configure las opciones:
CURLOPT_HEADER, 0
CURLOPT_RETURNTRANSFER, 1
y use curl_getinfo con CURLINFO_HTTP_CODE (o no opte param y tendrá una matriz asociativa con toda la información que desee)
Más en: http://php.net/manual/fr/function.curl-getinfo.php
fuente
curl_getinfo()
.Si desea específicamente el
Content-Type
, hay una opción especial de cURL para recuperarlo:fuente
Funciona con
HTTP/1.1 100 Continue
antes de otros encabezados.Si necesita trabajar con servidores con errores que envían solo LF en lugar de CRLF como saltos de línea, puede usar
preg_split
lo siguiente:fuente
$parts = explode("\r\n\r\nHTTP/", $response);
tener el tercer parámetro para explotar como 2?HTTP/1.1 100 Continue
Puede aparecer muchas veces.HTTP/1.1 100 Continue
Puede aparecer muchas veces. Él ve el caso si aparece solo una vez, pero está mal en el caso común. Por ejemplo, paraHTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 200 OK...\r\n\r\n...
su código no funciona correctamenteMi camino es
Si es necesario, aplique un bucle for y elimine el límite de explosión.
fuente
Aquí está mi contribución al debate ... Esto devuelve una matriz única con los datos separados y los encabezados enumerados. Esto funciona sobre la base de que CURL devolverá datos de un fragmento de encabezado [línea en blanco]
fuente
El problema con muchas respuestas aquí es que
"\r\n\r\n"
puede aparecer legítimamente en el cuerpo del html, por lo que no puede estar seguro de que está dividiendo los encabezados correctamente.Parece que la única forma de almacenar encabezados por separado con una llamada
curl_exec
es mediante una devolución de llamada como se sugiere anteriormente en https://stackoverflow.com/a/25118032/3326494Y luego (para obtener de manera confiable) solo el cuerpo de la solicitud, deberá pasar el valor del
Content-Length
encabezadosubstr()
como un valor de inicio negativo.fuente
list($head, $body) = explode("\r\n\r\n", $response, 2);
sin embargo, CURL ya lo hace por usted si usacurl_setopt($ch, CURLOPT_HEADERFUNCTION, $myFunction);
En caso de que no pueda / no use
CURLOPT_HEADERFUNCTION
u otras soluciones;fuente
Devuelve encabezados de respuesta con un parámetro de referencia:
fuente
$rtn=explode("\r\n\r\nHTTP/", $rtn, 2);
es correcto? ¿No debería eliminarse el tercer parámetro de explosión?explode("\r\n\r\n", $parts, 2);
así que ambos son correctos.Si realmente no necesitas usar curl;
Que salidas
Ver http://php.net/manual/en/reserved.variables.httpresponseheader.php
fuente