繁体   English   中英

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

[英]How can I send a raw JSON using PHP curl with the content type “application/x-www-form-urlencoded”?

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

让我解释:

我正在与一个Web服务器进行通信,该Web服务器接受带有JSON对象的HTTP POST请求作为请求的主体,通常我们通常会在其中查看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 ,但是服务器无法接受。

通常, application/x-www-form-urlencoded需要用于HTTP发布的键值配对参数。 因此,很难在不看到示例POST数据格式的情况下为您提供任何建议。 根据文档,您必须将URL编码的数据放入一个变量。 例如,您的JSON应该像这样。

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

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

$post_data = urlencode(json_encode($data_array))

我不太确定我是否理解您的问题,因此我将回答两个不同的版本。

发送JSON数据,但是使用(不正确的) application/x-www-form-urlencoded内容类型

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

$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而不是$json

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM