How can I find where I will be redirected using cURL?

前端 未结 7 1834
小鲜肉
小鲜肉 2020-11-22 03:53

I\'m trying to make curl follow a redirect but I can\'t quite get it to work right. I have a string that I want to send as a GET param to a server and get the resulting URL.

相关标签:
7条回答
  • 2020-11-22 04:20

    Add this line to curl inizialization

    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    

    and use getinfo before curl_close

    $redirectURL = curl_getinfo($ch,CURLINFO_EFFECTIVE_URL );
    

    es:

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT ,0); 
    curl_setopt($ch, CURLOPT_TIMEOUT, 60);
    $html = curl_exec($ch);
    $redirectURL = curl_getinfo($ch,CURLINFO_EFFECTIVE_URL );
    curl_close($ch);
    
    0 讨论(0)
  • 2020-11-22 04:22

    The answer above didn't work for me on one of my servers, something to to with basedir, so I re-hashed it a little. The code below works on all my servers.

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    $a = curl_exec($ch);
    curl_close( $ch ); 
    // the returned headers
    $headers = explode("\n",$a);
    // if there is no redirection this will be the final url
    $redir = $url;
    // loop through the headers and check for a Location: str
    $j = count($headers);
    for($i = 0; $i < $j; $i++){
    // if we find the Location header strip it and fill the redir var       
    if(strpos($headers[$i],"Location:") !== false){
            $redir = trim(str_replace("Location:","",$headers[$i]));
            break;
        }
    }
    // do whatever you want with the result
    echo redir;
    
    0 讨论(0)
  • 2020-11-22 04:35

    You can use:

    $redirectURL = curl_getinfo($ch,CURLINFO_REDIRECT_URL);
    
    0 讨论(0)
  • 2020-11-22 04:36

    The chosen answer here is decent but its case sensitive, doesn't protect against relative location: headers (which some sites do) or pages that might actually have the phrase Location: in their content... (which zillow currently does).

    A bit sloppy, but a couple quick edits to make this a bit smarter are:

    function getOriginalURL($url) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        $result = curl_exec($ch);
        $httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
    
        // if it's not a redirection (3XX), move along
        if ($httpStatus < 300 || $httpStatus >= 400)
            return $url;
    
        // look for a location: header to find the target URL
        if(preg_match('/location: (.*)/i', $result, $r)) {
            $location = trim($r[1]);
    
            // if the location is a relative URL, attempt to make it absolute
            if (preg_match('/^\/(.*)/', $location)) {
                $urlParts = parse_url($url);
                if ($urlParts['scheme'])
                    $baseURL = $urlParts['scheme'].'://';
    
                if ($urlParts['host'])
                    $baseURL .= $urlParts['host'];
    
                if ($urlParts['port'])
                    $baseURL .= ':'.$urlParts['port'];
    
                return $baseURL.$location;
            }
    
            return $location;
        }
        return $url;
    }
    

    Note that this still only goes 1 redirection deep. To go deeper, you actually need to get the content and follow the redirects.

    0 讨论(0)
  • 2020-11-22 04:37

    To make cURL follow a redirect, use:

    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    

    Erm... I don't think you're actually executing the curl... Try:

    curl_exec($ch);

    ...after setting the options, and before the curl_getinfo() call.

    EDIT: If you just want to find out where a page redirects to, I'd use the advice here, and just use Curl to grab the headers and extract the Location: header from them:

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $result = curl_exec($ch);
    if (preg_match('~Location: (.*)~i', $result, $match)) {
       $location = trim($match[1]);
    }
    
    0 讨论(0)
  • 2020-11-22 04:39

    Lot's of regex here, despite the fact i really like them this way might be more stable to me:

    $resultCurl=curl_exec($curl); //get curl result
    //Optional line if you want to store the http status code
    $headerHttpCode=curl_getinfo($curl,CURLINFO_HTTP_CODE);
    
    //let's use dom and xpath
    $dom = new \DOMDocument();
    libxml_use_internal_errors(true);
    $dom->loadHTML($resultCurl, LIBXML_HTML_NODEFDTD);
    libxml_use_internal_errors(false);
    $xpath = new \DOMXPath($dom);
    $head=$xpath->query("/html/body/p/a/@href");
    
    $newUrl=$head[0]->nodeValue;
    

    The location part is a link in the HTML sent by apache. So Xpath is perfect to recover it.

    0 讨论(0)
提交回复
热议问题