【问题标题】:Bad Request. Connecting to sites via curl on host and system错误的请求。通过主机和系统上的 curl 连接到站点
【发布时间】:2012-03-21 23:03:55
【问题描述】:

我在 php 中有这个 cURL 代码。

curl_setopt($ch, CURLOPT_URL, trim("http://stackoverflow.com/questions/tagged/java")); 
curl_setopt($ch, CURLOPT_PORT, 80); //ignore explicit setting of port 80
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_HTTPHEADER, $v);
curl_setopt($ch, CURLOPT_VERBOSE, true);

HTTPHEADER的内容是;

Proxy-Connection: Close
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1017.2 Safari/535.19
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: __qca=blabla
Connection: Close

它们每个都是数组$v 中的单独项。

当我在主机上上传文件并运行代码时,我得到的是:

400 错误请求

您的浏览器发送了无效请求。

但是当我使用命令行 PHP 在我的系统上运行它时,我得到的是

< HTTP/1.1 200 OK
< Vary: Accept-Encoding
< Cache-Control: private
< Content-Type: text/html; charset=utf-8
< Content-Encoding: gzip
< Date: Sat, 03 Mar 2012 21:50:17 GMT
< Connection: close
< Set-Cookie: buncha cokkies; path=/; HttpOnly
< Content-Length: 22151
< 
* Closing connection #0

.

它不仅在 stackoverflow 上发生,它也发生在 4shared 上,但适用于 google 和其他人。

感谢您的帮助。

【问题讨论】:

  • 删除curl_setopt($ch, CURLOPT_ENCODING, "");的结果是什么
  • @StefanN 浏览器将网页下载到.gz 文件中。它不显示。只需下载。

标签: php curl header


【解决方案1】:

根据http://php.net/manual/en/function.curl-setopt.php 尝试将CURLOPT_ENCODING 设置为"gzip"

另外,我会尽量避免使用尽可能多的标题行,例如使用CURLOPT_COOKIE 而不是Cookie: __qca__=blablaCURLOPT_USERAGENT

编辑:您似乎没有为 CURLOPT_HTTPHEADER 使用数组(键 => 值),是吗?在这种情况下,使用数组和其他东西,我写道,你会没事的。 (这是如何做到的,请阅读手册:P)

希望有帮助。

【讨论】:

    【解决方案2】:

    这更像是一个评论而不是一个答案:从你的问题中,不清楚是什么具体触发了 400 错误,也不清楚它的特别含义或更具体:它的来源。

    这是你的服务器的输出吗?这是您使用脚本输出的一些反馈(卷曲响应)吗?

    为了更好地调试,我提出了一种稍微不同的配置形式,您在使用 curl 扩展时可能会感兴趣。有一个很好的函数叫做curl_setopt_array,它允许你一次设置多个选项。如果其中一个选项失败,它将返回 false。它允许您在前面完整地配置您的请求。因此,您可以更轻松地注入并用第二个(调试)配置替换它:

    $curlDefault = array(
        CURLOPT_PORT => 80, // ignore explicit setting of port 80
        CURLOPT_RETURNTRANSFER => TRUE,
        CURLOPT_FOLLOWLOCATION => TRUE,
        CURLOPT_ENCODING => '',
        CURLOPT_HTTPHEADER => array(
            'Proxy-Connection: Close',
            'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1017.2 Safari/535.19',
            'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'Accept-Encoding: gzip,deflate,sdch',
            'Accept-Language: en-US,en;q=0.8',
            'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3',
            'Cookie: __qca=blabla',
            'Connection: Close',
        ),
        CURLOPT_VERBOSE => TRUE, // TRUE to output verbose information. Writes output to STDERR, or the file specified using CURLOPT_STDERR.
    );
    
    $url = "http://stackoverflow.com/questions/tagged/java";
    $handle = curl_init($url);
    curl_setopt_array($handle, $curlDefault);
    $html = curl_exec($handle);
    curl_close($handle);
    

    这可能会帮助您改进代码并进行调试。

    此外,您正在使用CURLOPT_VERBOSE 选项。这会将详细信息放入STDERR - 因此您无法再跟踪它。相反,您也可以将其添加到输出中以更好地查看发生了什么:

    ...
        CURLOPT_VERBOSE => TRUE, // TRUE to output verbose information. Writes output to STDERR, or the file specified using CURLOPT_STDERR.
        CURLOPT_STDERR => $verbose = fopen('php://temp', 'rw+'),
    );
    
    $url = "http://stackoverflow.com/questions/tagged/java";
    $handle = curl_init($url);
    curl_setopt_array($handle, $curlDefault);
    $html = curl_exec($handle);
    $urlEndpoint = curl_getinfo($handle, CURLINFO_EFFECTIVE_URL);
    echo "Verbose information:\n<pre>", !rewind($verbose), htmlspecialchars(stream_get_contents($verbose)), "</pre>\n";
    curl_close($handle);
    

    它给出了以下输出:

    Verbose information:
    * About to connect() to stackoverflow.com port 80 (#0)
    *   Trying 64.34.119.12...
    * connected
    * Connected to stackoverflow.com (64.34.119.12) port 80 (#0)
    > GET /questions/tagged/java HTTP/1.1
    Host: stackoverflow.com
    Proxy-Connection: Close
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1017.2 Safari/535.19
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: en-US,en;q=0.8
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
    Cookie: __qca=blabla
    Connection: Close
    
    < HTTP/1.1 200 OK
    < Cache-Control: private
    < Content-Type: text/html; charset=utf-8
    < Content-Encoding: gzip
    < Vary: Accept-Encoding
    < Date: Mon, 05 Mar 2012 17:33:11 GMT
    < Connection: close
    < Content-Length: 10537
    < 
    * Closing connection #0
    

    如果它们与请求/卷曲相关,它应该为您提供追踪事物所需的信息。然后,您可以轻松更改参数并查看它是否有所作为。还将您在本地安装的 curl 版本与服务器上的版本进行比较。要获取它,请使用curl_version

    $curlVersion = curl_version();
    echo $curlVersion['version']; // e.g. 7.24.0
    

    希望这可以帮助您追踪事情。

    【讨论】:

    【解决方案3】:

    这对我有用

    curl_setopt($ch, CURLOPT_VERBOSE, true);
    $verbose = fopen('php://temp', 'w+');
    curl_setopt($ch, CURLOPT_STDERR, $verbose); 
    
    $response = curl_exec($ch);
    
    rewind($verbose);
    $verboseLog = stream_get_contents($verbose);
    echo "Verbose information:\n<pre>", htmlspecialchars($verboseLog), "</pre>\n";
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-29
      • 2012-04-22
      • 2022-01-20
      • 2012-10-13
      • 1970-01-01
      • 2016-04-06
      • 2011-06-01
      • 2022-11-04
      相关资源
      最近更新 更多