ESP32无法正确读取POST请求体的问题排查与解决
问题:ESP32 HTTP服务器无法接收ESP32客户端发送的POST请求体
问题概述
用API测试工具(如Postman)向ESP32 HTTP服务器发送POST请求时,服务器能正常读取并解析请求体;但用ESP32客户端发送相同请求时,服务器完全获取不到请求体内容。
核心原因排查
1. 客户端请求头缺失必要字段
POST请求必须携带Content-Type和Content-Length头,API测试工具会自动补全这些字段,但ESP32客户端需要手动添加。没有这两个头,服务器无法识别请求体的格式和长度,会直接忽略请求体内容。
2. 客户端请求体发送不完整
ESP32客户端发送请求体时,如果未正确调用发送方法或未刷新缓冲区,可能导致数据发送不全,服务器接收到空的请求体。
3. 服务器端读取逻辑错误
如果服务器端未正确处理请求体的读取方式(比如误用了错误的API获取参数),也会导致无法获取内容。
代码修正方案
修正后的ESP32客户端代码
#include <WiFi.h> #include <HTTPClient.h> const char* ssid = "你的WiFi名称"; const char* password = "你的WiFi密码"; const char* serverUrl = "http://ESP32服务器IP/post"; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\nWiFi连接成功"); if (WiFi.status() == WL_CONNECTED) { HTTPClient http; http.begin(serverUrl); // 必须添加的请求头 http.addHeader("Content-Type", "application/x-www-form-urlencoded"); String postData = "temp=25&hum=60"; http.addHeader("Content-Length", String(postData.length())); int httpCode = http.POST(postData); if (httpCode > 0) { Serial.printf("请求状态码: %d\n", httpCode); Serial.printf("服务器响应: %s\n", http.getString().c_str()); } else { Serial.printf("请求失败,错误码: %d\n", httpCode); } http.end(); } } void loop() { delay(10000); // 每10秒发送一次请求 }
修正后的ESP32服务器代码
#include <WiFi.h> #include <WebServer.h> const char* ssid = "你的WiFi名称"; const char* password = "你的WiFi密码"; WebServer server(80); void handlePostRequest() { if (server.method() != HTTP_POST) { server.send(405, "text/plain", "仅支持POST方法"); return; } // 读取原始请求体 String requestBody = server.arg("plain"); if (requestBody.isEmpty()) { server.send(400, "text/plain", "请求体为空"); return; } // 解析表单格式的请求体(x-www-form-urlencoded) String temp = server.arg("temp"); String hum = server.arg("hum"); Serial.printf("收到温度: %s\n", temp.c_str()); Serial.printf("收到湿度: %s\n", hum.c_str()); server.send(200, "text/plain", "数据接收成功"); } void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\nWiFi连接成功"); Serial.printf("服务器IP: %s\n", WiFi.localIP().toString().c_str()); server.on("/post", handlePostRequest); server.begin(); } void loop() { server.handleClient(); }
关键修正说明
- 客户端必须添加
Content-Type和Content-Length:这两个头是服务器识别请求体的核心,缺失会导致服务器跳过请求体读取。 - 服务器用
server.arg("plain")读取原始请求体:如果是表单格式,也可以直接用server.arg("参数名")获取对应值,但前提是请求头正确。 - 客户端发送后调用
http.end():确保释放HTTP连接资源,避免后续请求异常。
内容的提问来源于stack exchange,提问作者isca_
相关产品推荐
相关产品推荐

