如何在 ESP32 服务器上处理带有 JSON 负载的 POST 请求?

How to handle POST request with JSON payload on ESP32 server?

我正在尝试从 ESP32 上的 http 服务器接收 json 数据,但每次我尝试访问 json 中的数据时,我都会遇到核心恐慌。 POST 请求是使用简单的 html 形式完成的:

<form method="post" enctype='text/plain'>
    <fieldset>
        <legend>Fermentation:</legend>
        <input name="type" type="radio" value="Ale" /> Ale <br />
        <input checked="checked" name="type" type="radio" value="Lager" /> Lager <br />
        <label for="primary-duration">Duration of primary</label><br />
        <input name="primary-duration" type="text" value="5" /> <br />
        <input type="submit" value="Submit"><br />

    </fieldset>
</form>

char *buf 包含来自 POST 的数据,如下所示:type=Lager primary-duration=5[=17=] 将数据读入 buf 后,我正在使用 cJSON

解析它
cJSON *root = cJSON_Parse(buf);

并提取“类型”对象

const cJSON *typeJSON = cJSON_GetObjectItemCaseSensitive(root, "type");

在获取我的 cJSON 对象后,它被 _IsString() 正确识别为字符串,但在尝试访问它时出现“LoadProhibited”恐慌。

if (cJSON_IsString(typeJSON) && (typeJSON->valuestring != NULL))
{
    printf("%s", typeJSON->valuestring);
}else if(cJSON_IsString(typeJSON))
{
    ESP_LOGE(SERVER_HANDLER_TAG, "String error: Not a string");
}else
{
    ESP_LOGE(SERVER_HANDLER_TAG, "String error: empty string"); //I am always here, trying to print string (typeJSON->valuestring) results in kernel panic
}

如有任何建议,我将不胜感激。

您的 <form> 具有属性 enctype='text/plain';这意味着 POST 正文将不包含在 JSON.

中编码的数据

确实,字符串 "type=Lager primary-duration=5" 无效 JSON。

不幸的是,enctype='application/json' 不可用,因此您必须手动序列化 form 的字段,然后使用 JSON 数据发出 POST 请求。

例如:

<form action="javascript:void(0);">
  <input type="text" id="mytext1" />
  <button onclick="submitData()">Submit</button>
</form>

<script>
  async function submitData() {
    const mytext1 = document.getElementById("mytext1").value;

    const body = { mytext1 };

    const response = await fetch("target_page", {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify(body)
    });

    // if your server responds with text
    const serverResponse = await response.text();

    ...
  }
</script>