2009-09-17 21 views
31

¿Cómo puedo obtener la URL de destino usando cURL cuando el código de estado HTTP es 302?¿Cómo puedo obtener la URL de destino usando cURL?

<?PHP 
$url = "http://www.ecs.soton.ac.uk/news/"; 
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL,$url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
$html = curl_exec($ch); 
$status_code = curl_getinfo($ch,CURLINFO_HTTP_CODE); 

if($status_code=302 or $status_code=301){ 
    $url = ""; 
    // I want to to get the destination url 
} 
curl_close($ch); 
?> 
+2

¿Alguna suerte en sus otras preguntas sin resolver? – GZipp

+0

debe aceptar la respuesta correcta (-1) – John

Respuesta

5

Tienes que agarrar el Lugar cabecera para la dirección URL redirigida.

+1

que necesita más molestias, como comprobar si es relativa, resolverla (a la URL base probablemente anterior en una redirección intermedia si hay varias páginas, etc.), es simplemente más fácil de usar ['CURLINFO_EFFECTIVE_URL'] (http://stackoverflow.com/a/4917416/367456). – hakre

2

El nuevo destino para un redireccionamiento 302 se encuentra en el campo de encabezado http "ubicación". Ejemplo:

HTTP/1.1 302 Found 
Date: Tue, 30 Jun 2002 1:20:30 GMT 
Server: Apache 
Location: http://www.foobar.com/foo/bar 
Content-Type: text/html; charset=iso-8859-1 

Sólo grep con una expresión regular.

Para incluir toda la información del encabezado HTTP, inclúyala en el resultado con la opción de curl CURLOPT_HEADER. Configurarlo con:

curl_setopt($c, CURLOPT_HEADER, true); 

Si simplemente desea curl para seguir la redirección utilizar CURLOPT_FOLLOWLOCATION:

curl_setopt($c, CURLOPT_FOLLOWLOCATION, true); 

De todos modos, no se debe utilizar el nuevo URI HTTP porque statuscode 302 es sólo una temporal redirigir.

1

Aquí hay una manera de obtener todos los encabezados devueltos por una solicitud http curl, así como el código de estado y una matriz de líneas de encabezado para cada encabezado.

$url = 'http://google.com'; 
$opts = array(CURLOPT_URL => $url, 
       CURLOPT_RETURNTRANSFER => true, 
       CURLOPT_HEADER => true, 
       CURLOPT_FOLLOWLOCATION => true); 

$ch = curl_init(); 
curl_setopt_array($ch, $opts); 
$return = curl_exec($ch); 
curl_close($ch); 

$headers = http_response_headers($return); 
foreach ($headers as $header) { 
    $str = http_response_code($header); 
    $hdr_arr = http_response_header_lines($header); 
    if (isset($hdr_arr['Location'])) { 
     $str .= ' - Location: ' . $hdr_arr['Location']; 
    } 
    echo $str . '<br />'; 
} 

function http_response_headers($ret_str) 
{ 
    $hdrs = array(); 
    $arr = explode("\r\n\r\n", $ret_str); 
    foreach ($arr as $each) { 
     if (substr($each, 0, 4) == 'HTTP') { 
      $hdrs[] = $each; 
     } 
    } 
    return $hdrs; 
} 

function http_response_header_lines($hdr_str) 
{ 
    $lines = explode("\n", $hdr_str); 
    $hdr_arr['status_line'] = trim(array_shift($lines)); 
    foreach ($lines as $line) { 
     list($key, $val) = explode(':', $line, 2); 
     $hdr_arr[trim($key)] = trim($val); 
    } 
    return $hdr_arr; 
} 

function http_response_code($str) 
{ 
    return substr(trim(strstr($str, ' ')), 0, 3); 
} 
0

Uso curl_getinfo($ch), y el primer elemento (url) indicaría la URL efectiva.

37

Se puede utilizar:

echo curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); 
+0

Este método es mucho más limpio/generalmente mejor que analizar la URL desde el encabezado de la ubicación. –

+10

CURLINFO_EFFECTIVE_URL devuelve la página actual (solicitada) por mí. No hay una URL de redireccionamiento (Ubicación :) en los resultados de curl_getinfo. Parece que analizar encabezados es la mejor práctica ... –

+0

'CURLINFO_EFFECTIVE_URL' no siempre funciona en algunos casos, especialmente en aquellos sin el uso de la redirección de encabezados. – Raptor

21
$ch = curl_init($url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 
curl_setopt($ch, CURLOPT_HEADER, TRUE); // We'll parse redirect url from header. 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE); // We want to just get redirect url but not to follow it. 
$response = curl_exec($ch); 
preg_match_all('/^Location:(.*)$/mi', $response, $matches); 
curl_close($ch); 
echo !empty($matches[1]) ? trim($matches[1][0]) : 'No redirect found'; 
+0

¡perfecto! Gracias por compartir – ladieu

+1

¿Y si no hay un encabezado de ubicación? –

+0

A veces, los sitios usarán la meta redirección o 'window.location.replace' para redirigir la página. En tal caso, reemplace la expresión regular para capturar el resultado. – Raptor

5

un poco anticuado de una respuesta, pero quería mostrar un ejemplo de trabajo completo, algunas de las soluciones por ahí son piezas:

$ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $url); //set url 
    curl_setopt($ch, CURLOPT_HEADER, true); //get header 
    curl_setopt($ch, CURLOPT_NOBODY, true); //do not include response body 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //do not show in browser the response 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); //follow any redirects 
    curl_exec($ch); 
    $new_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); //extract the url from the header response 
    curl_close($ch); 

Este funciona con redirecciones como 301 o 302, sin embargo, en 404 solo devolverá la url original solicitada (ya que no se encontró). Esto se puede utilizar para actualizar o eliminar enlaces de su sitio. Esta era mi necesidad de todos modos.

2

En respuesta al comentario de user437797 sobre la respuesta de Tamik Soziev (que por desgracia no tienen la reputación de comentar allí directamente):

El CURLINFO_EFFECTIVE_URL funciona bien, pero para que lo haga como PO quiere también hay que establecer CURLOPT_FOLLOWLOCATION a VERDAD, por supuesto. Esto es porque CURLINFO_EFFECTIVE_URL devuelve exactamente lo que dice, la url efectiva que termina siendo cargada. Si no sigue los redireccionamientos, esta será su url solicitada; si sigue los redireccionamientos, será la url final a la que se redireccionará.

Lo bueno de este enfoque es que también funciona con múltiples redireccionamientos, mientras que al recuperar y analizar el encabezado HTTP usted mismo puede tener que hacer eso varias veces antes de que se exponga la url de destino final.

También tenga en cuenta que el número máximo de redirecciones que curl sigue se puede controlar mediante CURLOPT_MAXREDIRS.Por defecto es ilimitado (-1) pero esto puede ocasionarle problemas si alguien (tal vez intencionalmente) configuró e interminablemente un bucle de redirección para alguna url.

Cuestiones relacionadas