在发送$ _POST请求后,使用Content-Disposition响应头进行curl工作

时间:2015-03-07 01:44:57

标签: php curl content-disposition

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

http://unblockproxy.nu/

尝试浏览任何网站,让我们说(http://www.example.com/samplepage.html)将其放入该字段,然后点击"取消阻止"按钮

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

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

响应浏览器的标题如下:

  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

这很简单,现在您使用此网络代理获得了浏览页面的内容。

现在,我想使用curl

做同样的工作

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

以下是一些模拟我的问题的代码::

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

这将返回http://unblockproxy.nu/的内容,而这不是我想要的内容(http://www.example.com/samplepage.html浏览的http://unblockproxy.nu/

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

谢谢。

2 个答案:

答案 0 :(得分:1)

试试这个。如果我能正确理解你的问题,这对我很有用。我删除了很多没有做任何事情的代码。事实证明,问题在于您没有在请求标头中设置referer

让我从头开始。在通过POST提交表单以查看具有代理的指定网站后,会向http://unblockproxy.nu/index.php发送请求。正如您在问题中提到的,index.php处理表单提交并生成HTTP status code of 302,它基本上只是将您重定向到另一个页面。假设您向index.php发送格式正确的请求,您可以解析响应标头并获取重定向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重定向到的网址,请按如下方式向其发送cURL请求。奇怪的是,几乎所有我修改过的其他请求标题在确定此解决方案是否有效方面都没有任何作用。您的代码获取http://unblockproxy.nu内容而不是http://unblockproxy.nu查看的给定网站内容的原因是因为您没有正确关注重定向并且您没有设置请求标头中的referer。 cookie,内容处理和所有其他标题似乎在解决这个问题上没有任何作用。

$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而不是绝对URL。请记住这一点。

答案 1 :(得分:0)

问题是它需要两次往返服务器来完成请求。许多网站使用该方法来减少“机器人”的数量或请求。第一个请求创建一个cookie(通常用于“会话”),该cookie必须存在才能处理表单。

执行curl_exec()两次,看看你是否得到了你想要的结果。响应将首次发送cookie,因为您启用了cookie后卷曲将保存。第二次你应该得到你想要的结果。