ESP32 ESPAsyncWebServer PUT请求传递JSON失败,如何修复?
ESP32 ESPAsyncWebServer PUT请求JSON数据处理问题修复
问题说明
使用ESP32的ESPAsyncWebServer处理PUT请求传递JSON时,PUT请求能触发服务器端代码,但始终返回"No Json!",无法获取请求体中的JSON数据。
可正常运行的代码
JavaScript(GET请求方式)
async function test() { var val = JSON.stringify({on: ledState}); xmlHttp.open("GET", "/test?json="+val, true); xmlHttp.send(); }
服务器端(GET请求处理)
server.on("/test", HTTP_GET, [](AsyncWebServerRequest *request){ if (startuart) Serial.println("led"); if (request->hasParam("json")) { String val = request->getParam("json")->value(); if (startuart) Serial.println(val); request->send(200, "text/plain", "OK"); } else { if (startuart) Serial.println("No Json!"); request->send(200, "text/plain", "No Json!\n"); } });
异常代码(无法正常获取JSON)
JavaScript(PUT请求方式)
async function led() { var val = JSON.stringify({on: ledState}); try { const response = await fetch("/led", { method: "PUT", body: val, headers: {"Content-Type": "text/plain"} }); } catch (error) {console.log("Request Failed: " + error);} }
服务器端(PUT请求处理)
server.on("/led", HTTP_PUT, [](AsyncWebServerRequest *request){ if (startuart) Serial.println("led"); if (request->hasParam("body")) { String val = request->getParam("body")->value().c_str(); // value().c_str(); if (startuart) Serial.println(val); request->send(200, "text/plain", "OK"); } else { if (startuart) Serial.println("No Json!"); request->send(200, "text/plain", "No Json!\n"); } });
修复方案
1. 前端JavaScript修改
发送PUT请求时,Content-Type应设置为application/json(匹配JSON数据格式):
async function led() { var val = JSON.stringify({on: ledState}); try { const response = await fetch("/led", { method: "PUT", body: val, headers: {"Content-Type": "application/json"} }); } catch (error) {console.log("Request Failed: " + error);} }
2. 服务器端代码修改
ESPAsyncWebServer中,PUT请求的原始请求体需要通过request->arg("plain")获取,而非hasParam("body"),同时修正字符串转换的错误:
server.on("/led", HTTP_PUT, [](AsyncWebServerRequest *request){ if (startuart) Serial.println("led"); // 检查是否存在原始请求体(plain参数对应raw body) if (request->hasArg("plain")) { String val = request->arg("plain"); if (startuart) Serial.println(val); request->send(200, "text/plain", "OK"); } else { if (startuart) Serial.println("No Json!"); request->send(200, "text/plain", "No Json!\n"); } });
原理说明
- 前端:设置正确的
Content-Type能让服务器明确请求数据格式,同时符合HTTP规范; - 后端:ESPAsyncWebServer将PUT/POST的原始请求体存储在
plain参数中,而非命名为body的参数,hasParam()仅用于URL查询参数或表单参数,无法直接获取请求体。
内容的提问来源于stack exchange,提问作者Володимир Дідик
相关产品推荐
相关产品推荐

