You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP32服务器处理JSON载荷POST请求及cJSON解析内核panic问题咨询

核心问题定位

你遇到的panic本质是传入cJSON解析的内容根本不是JSON格式,具体原因如下:

  • 你设置的表单enctype为text/plain,提交后服务端收到的POST payload格式是key1=value1 key2=value2,完全不符合JSON的语法规范(JSON要求键值对用双引号包裹、用大括号包裹结构,键值对之间用逗号分隔)
  • cJSON_Parse解析非法格式的输入时会直接返回NULL,你没有对root是否为NULL做校验,后续直接把空指针传入cJSON_GetObjectItemCaseSensitive,得到的typeJSON也是空指针
  • 后续你直接访问空指针typeJSON的成员valuestring,就触发了LoadProhibited类型的内存访问错误panic

解决方案

方案1:前端直接提交JSON格式数据(推荐,适配现有cJSON解析逻辑)

修改前端表单的提交逻辑,不要用原生表单默认提交,用JS拦截提交事件,把表单数据组装成JSON后提交:

<form id="fermForm">
    <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>
<script>
document.getElementById('fermForm').addEventListener('submit', function(e) {
    e.preventDefault();
    const formData = new FormData(this);
    const payload = Object.fromEntries(formData.entries());
    fetch('/你的提交接口地址', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(payload)
    });
});
</script>

此时服务端收到的payload就是合法JSON:{"type":"Lager","primary-duration":"5"},你的现有cJSON解析逻辑就能正常工作,注意要先加空指针校验,还要记得释放cJSON内存避免泄漏:

cJSON *root = cJSON_Parse(buf);
if (root == NULL) {
    ESP_LOGE(SERVER_HANDLER_TAG, "JSON解析失败,输入格式非法");
    return;
}
const cJSON *typeJSON = cJSON_GetObjectItemCaseSensitive(root, "type");
// 原有逻辑
cJSON_Delete(root);

方案2:后端解析text/plain格式的表单数据(不修改前端)

如果不想改前端,就不要用cJSON解析,直接拆分字符串提取键值对即可:

// buf内容为type=Lager primary-duration=5
char *key = strtok(buf, "= ");
char *val;
char type[16] = {0};
int primary_duration = 0;
while(key != NULL) {
    val = strtok(NULL, "= ");
    if (strcmp(key, "type") == 0) {
        strncpy(type, val, sizeof(type)-1);
    } else if (strcmp(key, "primary-duration") == 0) {
        primary_duration = atoi(val);
    }
    key = strtok(NULL, "= ");
}

内容的提问来源于stack exchange,提问作者vict

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 07:06:04