【问题标题】:PHP HTTP post - 400 Bad RequestPHP HTTP post - 400 错误请求
【发布时间】:2015-01-02 22:55:00
【问题描述】:

我不是专业的 PHP 程序员,但我不得不编写一个 PHP 脚本,该脚本将向 API 发送 HTTP POST 请求。这篇文章还包括一些 JSON 内容(我已使用 jsonlint.com 验证其格式正确)。我不断收到“400 Bad Request”,所以我假设我的某些内容格式不正确。

$json = "<JSON markup goes here>";

$options = array(
    'http' => array
    (
        'method'  => 'POST',
        'content' => $json,
        'header'  =>    "Content-Type: application/json\r\n" .
                "Accept: application/json\r\n" .
                "Api-User: <API USER GOES HERE>\r\n" .
                "Api-Key: <API KEY GOES HERE>\r\n"
    )
);

$url = "https://url/paths";

$context  = stream_context_create( $options );
$result   = file_get_contents( $url, false, $context );
$response = json_decode( $result );

我搜索了这个网站,大多数示例似乎与我正在做的事情相匹配……所以我不知道问题出在哪里。我注意到的一个区别(与示例相比)是我的发布到一个 HTTPS 网址......但从我读过的内容来看,这并没有太大的区别。你们能提供的任何帮助将不胜感激!

【问题讨论】:

  • 你连接的api是什么?他们通常会提供有关返回状态代码原因的文档。
  • 我没有看到任何“主机”标头。
  • 不幸的是,API 文档只说“由于语法错误,服务器无法理解请求。”为他们的 400 错误请求。 :-/ 这就是让我认为这是我在构建请求时做错的事情。
  • 错误 400 可能只是来自 API 的正常响应。例如,Mailchimp API 在尝试将现有用户添加到邮件列表时提供此功能。

标签: php http post http-status-code-400


【解决方案1】:

试试这样——不要把 json 作为字符串,而是使用 PHP:

$json = array("keys" => "values"); // You get the idea, right?  

$options = array(
    'http' => array
    (
        'method'  => 'POST',
        'content' => json_encode($json),
        'header'  =>    "Content-Type: application/json\r\n" .
                "Accept: application/json\r\n" .
                "Api-User: <API USER GOES HERE>\r\n" .
                "Api-Key: <API KEY GOES HERE>\r\n"
    )
);

【讨论】:

  • JSON 非常复杂,这就是我没有使用 PHP 构建它的原因。这是一个示例: {"content": {"templateId": "123456"},"updateProfile": true,"recipients": [{"email": "jerry.garcia@gmail.com","id": " jerry.garcia@gmail.com","profile": {"userAttrs": [{"lastName": "Garcia"},{"firstName": "Jerry"},{"Birth Date": "1942-08- 01"}]},"subscriptions": {"add": ["Banjo Lovers","9 finger club"]}}]} 如果你能帮我用你的方法格式化那个 JSON,那就太好了。跨度>
【解决方案2】:

我没有看到任何“主机”标题。不包括“主机”可能会导致错误请求。

例如:

POST http://localhost:8080/api/myService HTTP/1.1
Host: http://localhost:8080
Content-Type: application/json

{
    "id" : "value"
}

此外,文档中的所有示例都使用fopen 而不是file_get_contents。见http://php.net/manual/en/function.stream-context-create.php

编辑:这是一个例子……

$options = array(
    'http' => array
    (
        'method'  => 'POST',
        'content' => $json,
        'header'  => "Host: http://localhost:8080\r\n" .
                "Content-Type: application/json\r\n" .
                "Accept: application/json\r\n" .
                "Api-User: <API USER GOES HERE>\r\n" .
                "Api-Key: <API KEY GOES HERE>\r\n"
    )
);

$url = "http://localhost:8080/api/myService";

【讨论】:

  • 如何在 $options 数组中定义它?我假设它只是“主机:url/path”?主机是我的服务器还是他们的服务器(API 所在的位置)?
【解决方案3】:

你可能需要使用 curl:

<?php

function getCurl($url, $post) {

    $appName = 'My Application';
    $apiUser = [Username Goes Here];
    $apiKey = [API Key Goes Here];

    $baseUrl = "https://url/";
    $credentials = $apiUser:$apiKey;
    $typeHeader = "Content-Type: application/json";
    $helloHeader = "User-Agent: $appName ($appContact)";

    $url = $baseUrl.$url;

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_USERPWD, $credentials);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array($typeHeader, $helloHeader));
    return $ch;
}

$options = array(
    'http' => array
    (
        'method'  => 'POST',
        'content' => $json,
        'header'  =>    "Content-Type: application/json\r\n" .
                "Accept: application/json\r\n" .
                "Api-User: <API USER GOES HERE>\r\n" .
                "Api-Key: <API KEY GOES HERE>\r\n"
    )
);

$curl = getCurl("paths", $options);
echo curl_exec($curl).'</br>';
echo curl_errno($curl).'</br>';
echo curl_error($curl).'</br>';

?>

【讨论】:

  • 我试过这个方法,发送信息时似乎无法识别API用户名和密钥。有什么想法吗?
  • 不确定 - 可以尝试删除一些 curl_setopt,例如 CURLOPT_USERPWD,尤其是因为您在 $options 数组中提供了该信息
  • 投反对票,因为使用 CURL 不会改变错误并且比使用纯 PHP 更复杂。
猜你喜欢
  • 1970-01-01
  • 2019-05-28
  • 1970-01-01
  • 1970-01-01
  • 2014-03-05
  • 1970-01-01
  • 1970-01-01
  • 2017-06-29
  • 2023-03-11
相关资源
最近更新 更多