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

ESP32 Web服务器无法处理Web应用发送的JSON数据问题排查

问题分析与解决方案

你的核心问题出在两个关键地方:

  • manejaJson是AsyncWebServer专门用于multipart/form-data类型文件上传的回调函数,但前端发送的是JSON格式数据,并非文件上传请求,因此该回调不会被触发。
  • 主回调中提前调用了request->send(200),会直接结束HTTP请求,后续即使有数据处理逻辑也无法执行。

解决方案步骤

1. 调整ESP32端的请求处理逻辑

根据前端发送的JSON数据,我们不需要使用文件上传回调,改用onRequestBody处理原始请求体,或者直接解析表单数据(若调整前端发送格式)。以下是两种可行方案:

方案一:直接处理JSON格式请求体

修改ESP32的请求注册代码,去掉文件上传回调,改用onRequestBody接收JSON数据:

server.on("/forma-dato", HTTP_POST, [](AsyncWebServerRequest *request) {
    if(!request->authenticate(usuarioHTTP, claveHTTP)) {
      return request->requestAuthentication();
    }
    // 不要在这里调用send,等待数据处理完成后再响应
}, NULL, [](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) {
    // 这个回调用于接收请求体数据
    static String jsonBuffer;
    if(index == 0) {
        jsonBuffer = "";
        Serial.println("Recibiendo JSON desde " + request->client()->remoteIP().toString());
    }
    // 拼接数据
    jsonBuffer.concat((char*)data, len);
    if(index + len == total) {
        // 数据接收完成,处理JSON
        Serial.println("JSON completo: " + jsonBuffer);
        // 可添加ArduinoJson解析逻辑,示例:
        // DynamicJsonDocument doc(1024);
        // deserializeJson(doc, jsonBuffer);
        // String ssid = doc["ssid"].as<String>();
        
        // 处理完成后发送响应
        request->send(200, "application/json", "{\"status\":\"ok\"}");
        ultimaPaginaCargada = "/config.html";
    }
});

方案二:调整为处理表单数据(适配前端发送表单格式)

若希望保持表单处理逻辑,可修改前端发送application/x-www-form-urlencoded格式,ESP32端直接解析:

server.on("/forma-dato", HTTP_POST, [](AsyncWebServerRequest *request) {
    if(!request->authenticate(usuarioHTTP, claveHTTP)) {
      return request->requestAuthentication();
    }
    // 解析表单数据
    request->parseBody();
    // 根据表单字段名获取值,示例:
    String ssid = request->arg("ssid");
    String password = request->arg("password");
    Serial.println("Recibido ssid: " + ssid + ", password: " + password);
    
    ultimaPaginaCargada = "/config.html";
    request->send(200, "text/plain", "Configuración recibida");
});

2. 优化前端的请求发送代码

适配方案一(发送JSON)

简化代码,直接发送JSON字符串并设置正确的Content-Type:

if(document.getElementById("forma") != null) {
    var elementoForma = document.getElementById("forma");
    elementoForma.addEventListener("submit", function(e) {
        e.preventDefault();
        var datosForma = {};
        var formaDatos = new FormData(elementoForma);
        for(var [k,v] of formaDatos) {
            datosForma[k] = v;
        }
        var datosJson = JSON.stringify(datosForma);
        fetch("forma-dato", {
            method: "POST",
            headers: {
                "Content-Type": "application/json"
            },
            body: datosJson
        })
        .then(response => response.text())
        .then(data => console.log("Respuesta del servidor:", data))
        .catch(error => console.error("Error en la solicitud:", error));
    });
}

适配方案二(发送表单格式)

直接发送FormData,无需转JSON:

if(document.getElementById("forma") != null) {
    var elementoForma = document.getElementById("forma");
    elementoForma.addEventListener("submit", function(e) {
        e.preventDefault();
        var formaDatos = new FormData(elementoForma);
        fetch("forma-dato", {
            method: "POST",
            body: formaDatos
        })
        .then(response => response.text())
        .then(data => console.log("Respuesta del servidor:", data))
        .catch(error => console.error("Error en la solicitud:", error));
    });
}

额外注意事项

  • 确保ESP32的AsyncWebServer版本兼容,避免版本差异导致的问题。
  • 若使用JSON解析,建议引入ArduinoJson库简化处理,减少手动解析出错概率。
  • 测试时可通过浏览器控制台查看请求的网络详情,确认请求头、请求体是否正确发送。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 07:55:21