2009-09-17 52 views
31

當HTTP狀態碼是302時,如何使用cURL獲取目標URL?如何使用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

對其他未解決的問題有什麼好運? – GZipp 2009-09-18 03:34:42

+0

你應該接受正確的答案(-1) – John 2016-10-04 03:00:51

回答

5

你必須抓住位置頭用於重定向的URL。

+1

這需要更多的麻煩,比如檢查它是否是相對的,解決它(如果存在多個等pp的話,可能會在中間重定向中可能以前的基本URL),它只是更多易於使用['CURLINFO_EFFECTIVE_URL'](http://stackoverflow.com/a/4917416/367456)。 – hakre 2012-03-15 04:02:15

2

爲位於在HTTP報頭字段「位置」 302重定向IST的新的目的地。 實施例:

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 

與正則表達式只是grep顯示它。

要包含所有HTTP標頭信息,請將其包含到捲曲選項CURLOPT_HEADER的結果中。

curl_setopt($c, CURLOPT_HEADER, true); 

如果你只是想捲曲跟隨重定向使用CURLOPT_FOLLOWLOCATION:與將它設置

curl_setopt($c, CURLOPT_FOLLOWLOCATION, true); 

無論如何,因爲HTTP的StatusCode 302僅僅是一個你不應該使用新的URI臨時重定向。

1

這裏的一個方式來獲得由捲曲的http請求,以及狀態代碼和標題行的每個報頭中的陣列返回的所有標頭。

$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

使用curl_getinfo($ch),並且第一個元素(url)將指示有效的URL。

37

您可以使用:

echo curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); 
+0

這個方法更清晰/通常更好,然後從位置標題解析出url。 – 2012-05-09 08:16:42

+10

CURLINFO_EFFECTIVE_URL爲我返回當前(請求)頁面。 curl_getinfo結果中沒有重定向(Location :) url。看來,解析頭文件是最佳實踐... – 2012-11-12 16:15:11

+0

'CURLINFO_EFFECTIVE_URL'並不總是適用於某些情況,尤其是那些不使用頭重定向的情況。 – Raptor 2015-04-21 09:14:56

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

完美!感謝分享 – ladieu 2013-03-03 20:36:47

+1

如果沒有位置標題? – 2014-09-01 23:50:18

+0

有時候網站會使用meta重定向或'window.location.replace'來重定向頁面。在這種情況下,請替換正則表達式以捕獲結果。 – Raptor 2015-04-21 09:14:10

5

日的反應卻有點想展示一個完整的工作例如,一些解決方案的出有件:

$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); 

這適用於任何重定向,如301或302,但在404上它只會返回請求的原始URL(因爲找不到)。這可用於更新或刪除您網站的鏈接。無論如何,這是我的需要。

2

在迴應Tamik Soziev的回答user437797的評論(我遺憾的是沒有信譽直接評論那裏):

的CURLINFO_EFFECTIVE_URL工作正常,但它爲運做希望你也必須設置CURLOPT_FOLLOWLOCATION當然是TRUE。這是因爲CURLINFO_EFFECTIVE_URL完全返回它所說的,最終得到加載的有效url。如果您不遵循重定向,那麼這將是您請求的網址,如果您確實遵循重定向,那麼它將成爲重定向到的最終網址。

這種方法的好處在於它也可以處理多個重定向,而當您自己檢索並解析HTTP頭時,您可能必須多次執行該操作,然後才能顯示最終目標網址。

另請注意,可以通過CURLOPT_MAXREDIRS控制捲曲所遵循的最大重定向次數。默認情況下它是無限的(-1),但如果有人(可能是有意的)配置並且無休止地重定向某個url的循環,這可能會讓你陷入麻煩。