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
相关产品推荐
相关产品推荐

