簡體   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