PHP Bad Request中的HTTP请求失败

时间:2016-04-28 13:37:55

标签: php http

我可以直接从浏览器请求URL Web服务'WS',但是当我在我的代码中使用file_get_contents()或fopen方法时,我收到一条错误消息。有人在没有使用卷曲的情况下有解决方案吗?

public function sendHttpRequest($data) {
   ini_set('user_agent', 'PHP');

    $context_options = array(
        'http' => array(
            'method' => 'POST',
            'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
            'content' => json_encode($data)
        )
    );


    $context = stream_context_create($context_options);

    //line error "line 196"
    $result = file_get_contents($this->WS, false, $context);
}

错误讯息:

  

无法打开流:HTTP请求失败! HTTP / 1.1 400错误请求    在第196行的/mnt/hgfs/case/src/bat/abc/send-entry.php

     

NULL

我已将上下文选项更改为此选项,但仍然获得HTTP/1.1 400 Bad Request

$context_options = array(
        'http' => array(
            'method' => 'POST',
            'header' => "Date: " . gmdate("D, d M Y H:i:s T", time()) . "\r\n"
            . get_headers($this->WS)[2] . "\r\n"
            . " x-powered-by: PHP/" . phpversion() . "\r\n"
            . " " . get_headers($this->WS)[5] . "\r\n"
            . " Pragma: no-cache" . "\r\n"
            . " Content-Length: " . strlen($this->content) . "\r\n"
            . " Content-Type: text/xml" . "\r\n"
            . " " .get_headers($this->WS)[9] . "\r\n"
            . " Connection: close",
            'content' => $this->content
        )

var_dump(get_headers($this->WS))

将数据发送到地址为http://192.168.xxx.xxx/WS

的服务器

这是要发送的数组的var_dump

array(16) {
  ["method"]=>
  string(24) "WS"
  ["LOGIN"]=>
  string(12) "xxx"
  ["DATE1"]=>
  string(10) "1970-01-01"
  ["DATE2"]=>
  string(0) ""
  ["TRANSMISSION"]=>
  INT(8)
  ["REF"]=>
  int(206)
  ["FORMAT"]=>
  int(7)
  ["DOMAIN"]=>
  int(3)
  ["TYPE1"]=>
  int(15)
  ["TYPE2"]=>
  NULL
  ["NAME"]=>
  string(12) "JDOE"
  ["ADRESSE"]=>
  string(0) ""
  ["ADRESSE2"]=>
  string(0) ""
  ["ADRESSE3"]=>
  string(0) ""
  ["ADRESSE4"]=>
  string(0) ""
  ["REF2"]=>
  string(0) ""
}

这是完整的消息错误

  

警告:file_get_contents(http://192.168.xxx.xxx/WS):无法打开流:HTTP请求失败! HTTP / 1.1 400错误请求    在第182行的/mnt/hgfs/case/src/bat/abc/send-entry.php中

工作代码:

    $context_options1 = array(
        'http' => array(
            'method' => 'POST',
            'header' => "Date: " . gmdate("D, d M Y H:i:s T", time())
            . "Accept: application/xml"
            . "Content-Type: application/xml"
            . "Content-Length: " . strlen($this->content),
            'content' => $this->content
        )
    );

3 个答案:

答案 0 :(得分:2)

POST请求需要Content-Length标头:

$content = json_encode($data);
$context_options = array(
        'http' => array(
            'method' => 'POST',
            'header' => "Content-Type: application/x-www-form-urlencoded\r\n" 
                         . "Content-Length: " . strlen($content) . "\r\n",
            'content' => $content
        )
    );

这显然是由包装器自动完成的,所以还有别的东西。也许省略标题中的最后一个换行符(" \ r \ n")。

答案 1 :(得分:1)

首先模拟您的浏览器。检查开发人员工具哪个标题完全发送给服务。并模仿它。这将有助于找到出错的地方。

例如,Service可能需要“Content-type:multipart / form-data”而不是Application / x-form类型。可能需要提供内容编码或其他内容。

答案 2 :(得分:0)

我怀疑这是由于宣布的mediatype与实际有效载荷之间的不匹配。正确的状态代码为415: Unprocessable Entity,但也可能出现400。

首先举例说明:您正在宣布来自html表单的urlencoded数据,后跟JSON。我认为这里的代码是正确的:

public function sendHttpRequest($data) {
    $data = json_encode($data)

    $context = stream_context_create(array(
        'http' => array(
            'method' => 'POST',
            'header' => array(
                'Content-Type: application/json',
                'Content-Length: ' . strlen($data),
                'Connection: close',
            ),
            'content' => $data,
        ),
    ));

    $result = file_get_contents($this->WS, false, $context);
}

您似乎也在请求中添加了很多标题,这些标题根本不属于Pragma和其他缓存控制标头。这些应该由服务器发送,而不是客户端。

此外,根据this answer确保$this->WS包含的所有内容都已正确编码。