Arduino(带以太网盾)发送JSON格式POST请求时请求体为空问题排查
问题分析与解决方案
我看了你的代码,发现两个违反HTTP协议规范的关键问题,这直接导致服务器无法正确解析你的POST请求体:
1. POST请求行缺少HTTP版本
HTTP请求的第一行必须明确指定版本信息,否则服务器可能无法按照标准逻辑处理请求。你原来的代码写的是:
client.println("POST /routes/test");
正确写法应该补充HTTP版本:
client.println("POST /routes/test HTTP/1.1");
2. 请求头与请求体之间的空行位置错误
HTTP协议要求:所有请求头发送完毕后,必须发送一个空行来分隔请求头和请求体。你的代码在POST行之后就提前发送了空行,这会让服务器误以为请求头已经结束,后续的Host、Content-Type等头信息都会被当成无效内容,而真正的JSON数据也无法被识别为请求体。
你原代码的错误顺序:
client.println("POST /routes/test"); client.println(); // 这里的空行位置完全错了! client.println("Host: x.x.x.x"); ... client.println(measureJson(doc)); serializeJson(doc, client);
正确逻辑是:发送完所有请求头(包括Content-Length)之后,再发送空行,最后才发送JSON请求体。
修正后的完整代码
#include <ArduinoJson.h> #include <Ethernet.h> #include <SPI.h> byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; byte ip[] = { 10, 0, 0, 177 }; byte server[] = { x, x, x, x }; // 替换为你的服务器实际IP EthernetClient client; void setup() { // 初始化以太网并设置1秒延迟 Ethernet.begin(mac, ip); Serial.begin(9600); delay(1000); Serial.println("connecting..."); if (client.connect(server, 5000)) { Serial.println("connected"); } else { Serial.println("connection failed"); return; // 连接失败直接退出,避免后续无效操作 } // 创建JSON文档并写入属性 const size_t capacity = JSON_OBJECT_SIZE(1); DynamicJsonDocument doc(capacity); doc["name"] = "some random name"; // 提前计算JSON长度,用于Content-Length字段 size_t jsonLength = measureJson(doc); // 发送POST请求(已修正HTTP版本) Serial.println("Begin POST Request"); client.println("POST /routes/test HTTP/1.1"); // 发送所有请求头 client.print("Host: "); client.println("x.x.x.x"); // 替换为你的服务器IP字符串 client.println("User-Agent: Arduino/1.0"); client.println("Content-Type: application/json;charset=UTF-8"); client.println("Connection: close"); client.print("Content-Length: "); client.println(jsonLength); // 关键:发送空行分隔请求头与请求体 client.println(); // 发送JSON请求体 serializeJson(doc, client); // 修正笔误:把Get改成POST Serial.println("Sent POST Request"); } void loop() { // 读取服务器响应,方便调试 while (client.available()) { char c = client.read(); Serial.print(c); } if (!client.connected()) { Serial.println(); Serial.println("disconnecting."); client.stop(); while(true); // 连接断开后停止程序 } }
额外说明
- 我修正了你的笔误:把"Sent Get Request"改成了"Sent POST Request",避免混淆。
- 添加了
loop()函数来读取服务器的响应,这样你可以在串口看到服务器返回的信息,方便排查后续问题。 - 连接失败后增加了
return语句,避免后续代码继续执行浪费资源。
这些修改完全遵循HTTP 1.1协议规范,服务器应该能正确识别到你的JSON请求体了。
内容的提问来源于stack exchange,提问作者Wendell
相关产品推荐
相关产品推荐

