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

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_

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 02:51:25