在发送 $_POST 请求后,让 curl 与响应 header 的 Content-Disposition 一起工作

get curl work with Content-Disposition of the response header after sending $_POST request

好的,要了解问题,请先访问

http://unblockproxy.nu/

尝试浏览任何网站,假设 (http://www.example.com/samplepage.html) 将其放入该字段然后单击 "unblock" 按钮

发送 $_POST 请求后,站点应将您重定向到类似以下内容:

http://unblockproxy.nu/index.php?x=Mfv0KjYRb3J3JO50MgBNbplFn2sTMoqPUIu1Unqn0bqdUoq5VbA9OnO8%3D

浏览器的响应Headers是这样的:

  HTTP/1.1 302 Found
  Date: Fri, 06 Mar 2015 12:49:30 GMT
  Server: Apache/2.2.15
  x-powered-by: PHP/5.3.3
  Location: http://unblockproxy.nu/index.php?x=Mfv0KjYRb3J3JO50MgBNbplFn2sTMoqPUIu1Unqn0bqdUoq5VbA9OnO8%3D
  Cache-Control: max-age=600, private, must-revalidate
  Expires: Fri, 06 Mar 2015 12:59:30 GMT
  Vary: Accept-Encoding
  Connection: close
  Content-Type: text/html; charset=UTF-8
  Transfer-Encoding: chunked

  HTTP/1.1 200 OK
  Date: Fri, 06 Mar 2015 12:49:34 GMT
  Server: Apache/2.2.15
  X-Powered-By: PHP/5.3.3
  Content-Disposition: inline; filename="samplepage.html"
  Cache-Control: max-age=600, private, must-revalidate
  Expires: Fri, 06 Mar 2015 12:59:34 GMT
  Vary: Accept-Encoding
  Connection: close
  Content-Type: text/html; charset=UTF-8
  Transfer-Encoding: chunked

这很简单,现在您可以使用此 Web 代理获取浏览页面的内容。

现在,我想用 curl 做同样的工作

我的问题是,我不知道如何让 curl 处理 Content-Disposition 的响应 header

这里有一些代码来模拟我的问题::

 $ch = curl_init();
 curl_setopt($ch, CURLOPT_URL, 'http://unblockproxy.nu/index.php');

 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
 curl_setopt($ch, CURLOPT_MAXREDIRS, 5);

 curl_setopt($ch, CURLOPT_POST, 1);
 curl_setopt($ch, CURLOPT_POSTFIELDS, array('x' => 'http://www.example.com/samplepage.html'));

 curl_setopt($ch, CURLOPT_COOKIESESSION, 1);
 curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
 curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');

 $string = curl_exec($ch);
 curl_close($ch);

 echo $string;

这将 return http://unblockproxy.nu/ 的内容,这不是我想要的(http://www.example.com/samplepage.html 冲浪通过 http://unblockproxy.nu/)

如果您想查看本站点的脚本(仅限 2 PHP 个文件),您可以 go here

谢谢。

试试这个。如果我正确理解您的问题,这对我来说很好用。我删除了很多什么都不做的代码。事实证明,问题是您没有在请求 headers.

中设置 referer

让我从头说起。通过 POST 提交表单以查看带有代理的给定网站后,请求将发送到 http://unblockproxy.nu/index.php. As you mentioned in your question, index.php handles the form submission and generates an HTTP status code of 302,这实际上只是将您重定向到另一个页面。假设您向 index.php 发送格式正确的请求,您可以解析响应 headers 并获取重定向的值 URL。按照下面的代码获取重定向 URL.

/**
 * Submit the form via POST
 * @param [site_url] The link to the page that you want to view 
 * eg: http://sitetoget.com/page.html
 * @return A string containing the response headers
*/
function GetRedirect($site_url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'http://unblockproxy.nu/index.php');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, array('x' => $site_url));
    $response = curl_exec($ch);
    curl_close($ch);
    return $response;
}

/**
 * Turn a header string into an associative array
 * @param [response] The response headers from the form submission 
 * @return An array containing all of the headers
*/
function GetHeaders($response) {
    $headers = [];
    $text = substr($response, strpos($response, "\r\n\r\n"));

    foreach(explode("\r\n", $text) as $i => $line) {
        if($i === 0 || $i == 1) {
            $headers['http_code'] = $line;
        } else {
            list($key, $value) = explode(': ', $line);

            if($key != '' && $value != '') {
                $headers[$key] = $value;
            }
        }
    }

    return $headers;
}

// Get the redirect URL
$redirect = GetRedirect('http://lancenewman.me/');
// Parse the response headers
$headers = GetHeaders($redirect);
// Save the redirect URL 
$new_url = $headers['Location'];

现在您已经有了 index.php 重定向到的 URL,向它发送一个 cURL 请求,如下所示。奇怪的是,我修改过的几乎所有其他请求 headers 在确定此解决方案是否有效时都没有发挥任何作用。您的代码获取 http://unblockproxy.nu 的内容而不是 http://unblockproxy.nu 查看的给定站点内容的原因是因为您没有正确遵循重定向并且没有设置 referer 在请求中 headers。 cookie content-disposition 和所有其他 headers 似乎在解决这个问题上没有任何作用。

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $new_url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_REFERER, 'http://unblockproxy.nu');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$string = curl_exec($ch);
curl_close($ch);

echo $string;

请务必注意,某些页面上的某些图像、CSS 和 JS 可能无法正确加载,因为某些页面使用相对 URL 而不是绝对的。请记住这一点。

问题是它需要两次往返服务器才能完成请求。许多站点使用该方法将请求数减少 "bots"。第一个请求创建一个 cookie(通常用于 "session"),必须存在该 cookie 才能处理表单。

执行 curl_exec() 两次,看看是否得到您想要的结果。第一次响应将发送一个 cookie,由于您启用了 cookie,curl 将保存该 cookie。第二次你应该得到你想要的结果。