curl_getinfo函數返回大量關於HTTP請求結果的元數據。但是,由於某些原因,它不包含我目前想要的信息位,如果請求返回HTTP重定向代碼,那麼這是目標URL。PHP cURL:獲取重定向目標,但不關注它
我沒有使用CURLOPT_FOLLOWLOCATION,因爲我想處理特定的重定向代碼作爲特殊情況。
如果cURL可以遵循重定向,爲什麼它不能告訴我他們在不跟隨它們時重定向到什麼?
當然,我可以設置CURLOPT_HEADER標誌並挑選位置標題。但是有沒有更高效的方法?
curl_getinfo函數返回大量關於HTTP請求結果的元數據。但是,由於某些原因,它不包含我目前想要的信息位,如果請求返回HTTP重定向代碼,那麼這是目標URL。PHP cURL:獲取重定向目標,但不關注它
我沒有使用CURLOPT_FOLLOWLOCATION,因爲我想處理特定的重定向代碼作爲特殊情況。
如果cURL可以遵循重定向,爲什麼它不能告訴我他們在不跟隨它們時重定向到什麼?
當然,我可以設置CURLOPT_HEADER標誌並挑選位置標題。但是有沒有更高效的方法?
沒有有沒有更有效的方法
你可以使用CURLOPT_WRITEHEADER + VariableStream
所以..你可以寫頭變量並解析它
似乎爲我的目的矯枉過正......也許我現在只是使用一個簡單的回調我已經成功地理解了它們。 – Stewart 2011-02-26 12:21:09
curl
似乎並不具備的功能或選項,以獲取
從響應:
Apache可以響應重定向目標,則可以使用各種技術來提取在301重定向的情況下使用HTML頁面(似乎302不是這種情況)。
如果響應具有類似的格式:使用DOMXPath
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="http://www.xxx.yyy/zzz">here</a>.</p>
<hr>
<address>Apache/2.2.16 (Debian) Server at www.xxx.yyy Port 80</address>
</body></html>
您可以提取重定向URL:
$i = 0;
foreach($urls as $url) {
if(substr($url,0,4) == "http") {
$c = curl_init($url);
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
$result = @curl_exec($c);
$status = curl_getinfo($c,CURLINFO_HTTP_CODE);
curl_close($c);
$results[$i]['code'] = $status;
$results[$i]['url'] = $url;
if($status === 301) {
$xml = new DOMDocument();
$xml->loadHTML($result);
$xpath = new DOMXPath($xml);
$href = $xpath->query("//*[@href]")->item(0);
$results[$i]['target'] = $href->attributes->getNamedItem('href')->nodeValue;
}
$i++;
}
}
使用CURLOPT_NOBODY
然而有一個更快的方法,如@gAMBOOKa指出;使用CURLOPT_NOBODY
。這種方法僅發送HEAD
請求而不是GET
(不下載實際內容,所以它應該更快,更高效)並存儲響應頭。
使用一個正則表達式的目標URL可以從報頭中提取:
foreach($urls as $url) {
if(substr($url,0,4) == "http") {
$c = curl_init($url);
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_NOBODY,true);
curl_setopt($c, CURLOPT_HEADER, true);
$result = @curl_exec($c);
$status = curl_getinfo($c,CURLINFO_HTTP_CODE);
curl_close($c);
$results[$i]['code'] = $status;
$results[$i]['url'] = $url;
if($status === 301 || $status === 302) {
preg_match("@https?://([-\w\.]+)+(:\d+)?(/([\w/_\-\.]*(\?\S+)?)?)[email protected]",$result,$m);
$results[$i]['target'] = $m[0];
}
$i++;
}
}
CURLOPT_NOBODY獲勝!不可缺少的......謝謝! – Gor 2013-08-09 02:44:04
這可以在4個簡單的步驟來完成:
步驟1.初始化捲曲
curl_init($ch); //initialise the curl handle
//COOKIESESSION is optional, use if you want to keep cookies in memory
curl_setopt($this->ch, CURLOPT_COOKIESESSION, true);
步驟2.獲取標題$url
curl_setopt($ch, CURLOPT_URL, $url); //specify your URL
curl_setopt($ch, CURLOPT_HEADER, true); //include headers in http data
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); //don't follow redirects
$http_data = curl_exec($ch); //hit the $url
$curl_info = curl_getinfo($ch);
$headers = substr($http_data, 0, $curl_info['header_size']); //split out header
步驟3.檢查,如果你有正確的響應代碼
if (!($curl_info['http_code']>299 && $curl_info['http_code']<309)) {
//return, echo, die, whatever you like
return 'Error - http code'.curl_info['http_code'].' received.';
}
第4步。解析頭以獲得新的URL
preg_match("!\r\n(?:Location|URI): *(.*?) *\r\n!", $headers, $matches);
$url = $matches[1];
一旦你有了新的URL,那麼你可以經常爲你喜歡重複步驟2-4。
我有同樣的問題,並curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
有任何幫助。
所以,我決定不使用CURL
但file_get_contents
代替:
$data = file_get_contents($url);
$data = str_replace("<meta http-equiv=\"Refresh\" content=\"0;","<meta",$data);
最後一行幫我擋住重定向雖然該產品是不是一個乾淨的HTML代碼。
我解析了數據並可以檢索我想要獲得的重定向URL。
它在我看來,好像您嘗試阻止重定向的頁面使用元刷新,而不是HTTP重定向。後者是我正在處理的。 – Stewart 2015-12-29 01:38:44
您可以簡單地使用它:(CURLINFO_REDIRECT_URL)
$info = curl_getinfo($ch, CURLINFO_REDIRECT_URL);
echo $info; // the redirect URL without following it
正如你所說,禁用CURLOPT_FOLLOWLOCATION選項(在執行前),並把我的代碼執行後。
CURLINFO_REDIRECT_URL - 隨着CURLOPT_FOLLOWLOCATION選項 禁用:重定向在過去的交易中發現的網址,應該 請手動旁邊。啓用CURLOPT_FOLLOWLOCATION選項 :這是空的。在這種情況下,重定向URL可在 CURLINFO_EFFECTIVE_URL
CURLOPT_NOBODY? – HyderA 2011-02-23 12:59:11
我的程序實際上使用了正文,在URL不是重定向的情況下。所以這根本不會改善事情。我的查詢基本上是關於是否有一種提取位置標題的方法,以節省在PHP代碼中執行它的開銷。 – Stewart 2011-02-23 16:40:06
http://stackoverflow.com/questions/1439040/how-can-i-get-the-destination-url-using-curl – 2016-05-26 17:00:34