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

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,提问作者Володимир Дідик

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 10:55:50