1

如何使用内容类型为的 PHP curl 发送原始 JSON application/x-www-form-urlencoded

让我解释:

我正在与一个接受HTTP POST请求的网络服务器通信,该请求使用 JSON 对象作为请求的主体,通常我们习惯于查看 HTTP 查询参数。

在我的情况下,我需要发送具有以下内容类型的请求

内容类型:application/x-www-form-urlencoded

正文必须是原始 JSON。

所以,有很多可能性。我尝试了以下方法:

<?php
      $server_url = "http://server.com";
      $curl = curl_init($server_url);
      $data_array = array("a"=> "a_val", "b" => array("c"=>"c_val", "d"=>"d_val") );

 $options = array(
       CURLOPT_POST            => TRUE,
       CURLOPT_HTTPHEADER     => array('Content-Type: application/x-www-form-urlencoded'),
       CURLOPT_POSTFIELDS      => json_encode($data_array),
       CURLOPT_COOKIEJAR       => realpath('tmp/cookie.txt'),
       CURLOPT_COOKIEFILE      => realpath('tmp/cookie.txt')
        );

    curl_setopt_array($curl, $options);
    $return = curl_exec($curl);  
    var_dump($return);  
    curl_close($curl);
?>

我也试图逃避json_encode()

...    
CURLOPT_POSTFIELDS      => "\"" . json_encode($data_array) .  "\"" ,
...

如果服务器能够解析 html 参数,我可以这样做:

...    
CURLOPT_POSTFIELDS      => http_build_query($data_array)
...

但是,事实并非如此,我需要一种解决方法。

请注意,更改内容类型将不起作用。我尝试使用text/plain,但服务器不接受它。

4

2 回答 2

2

通常application/x-www-form-urlencoded,HTTP post 需要一个键值对参数。因此,如果没有看到示例 POST 数据格式,很难向您提出任何建议。根据文档,您必须将 URL 编码数据与变量一起放置。例如,您的 JSON 应该是这样的。

$post_data = "data=".urlencode(json_encode($data_array))

您可以尝试发送没有任何关键参数的数据,它应该不起作用

$post_data = urlencode(json_encode($data_array))
于 2014-01-04T10:46:52.607 回答
0

我不完全确定我理解你的问题,所以我将回答两个不同的版本。

application/x-www-form-urlencoded发送 JSON 数据,但内容类型(不准确)

我不知道你为什么要这样做,但如果你这样做,它应该相当简单。

$data_array = array(
    'a' => 'a_val',
    'b' => array(
        'c' => 'c_val',
        'd' => 'd_val'
    )
);

$json = json_encode($data_array);

$c = curl_init();
curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_POST, true);
curl_setopt($c, CURLOPT_USERAGENT, 'PHP/' . phpversion());
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_POSTFIELDS, $json);
curl_setopt($c, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
$result = curl_exec($c);
if (curl_errno($c)) {
    return trigger_error('CURL error [' . curl_errno($c) . '] ' . curl_error($c));
}
curl_close($c);

echo $result;

请记住,您在这里故意向服务器发送不准确的数据。您正在发送 JSON,但将其称为 urlencoded。您可能不想这样做;如果出于某种原因,您确实需要这样做,那么您最好还是解决真正的问题,而不是使用这种骇人听闻的解决方法。

如果你使用 Guzzle 而不是 cURL,它可能会有点棘手。Guzzle 内置了对 JSON 和 urlencoded 的支持,但如果你想这样搞砸,最好不要使用它。自己生成 JSON 数据(使用$json = json_encode($data)),并在 Guzzle 中手动设置 Content-Type。

发送 urlencoded JSON 数据

这是一个奇怪的设置,但准确。至少你不会躺在你的 HTTP 标头中。

基本上和上面一样,但是添加这个:

$json = json_encode($data_array);
$data = array('JSON' => $json);
$body = http_build_query($data);

然后设置CURLOPT_POSTFIELDS$body而不是 to $json

您可能真正应该做的:将 JSON 作为 JSON 发送。

在大多数情况下,最好发送 JSON 数据(如示例一),并将 Content-Type 设置为application/json. 这是比示例二更小的数据大小(urlencoding 步骤增加了数据的大小),并且它具有准确的标头数据。

于 2016-02-29T11:45:50.630 回答