ESP8266向WebAPI发送数据返回400错误,请求排查解决
ESP8266发送JSON数据到WebAPI返回400错误的解决方法
问题描述
我尝试将ESP8266的传感器状态数据发送至WebAPI,但请求失败并返回400错误。设备可正常连接WiFi,但发送数据时API返回如下错误:
400 {"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"traceId":"00-862f434a8be85865c871ea45b89544d1-cea4232cafaa5cc1-00","errors":{"status":["The status field is required."]}}
手动调用该API可正常接收数据,但ESP8266无法成功发送。
所用ESP8266代码
#include <Arduino.h> #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <ESP8266HTTPClient.h> const char *ssid = "VRU"; const char *password = ""; const char *host = "192.168.174.71"; WiFiClient wifiClient; void setup() { delay(1000); Serial.begin(115200); WiFi.mode(WIFI_OFF); delay(1000); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); Serial.println(""); Serial.print("Connecting"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("Connected to "); Serial.println(ssid); Serial.print("IP address: "); Serial.println(WiFi.localIP()); } void loop() { HTTPClient http; http.begin(wifiClient,"http://192.168.174.71:100/api/StatusReport/AddStatus"); http.addHeader("Content-Type", "application/json"); int httpCode = http.POST("{\"status\":\"1\"}"); String payload = http.getString(); Serial.println(httpCode); Serial.println(payload); http.end(); delay(5000); }
问题分析与解决方法
从错误信息来看,API判定请求中缺少必填的status字段,但手动调用正常,说明问题出在ESP8266的请求构造上,以下是几种排查和解决思路:
1. 优化JSON字符串构造方式
手动拼接JSON容易出现隐性格式错误,比如转义问题或字符编码问题。可以尝试先将JSON存入字符串变量再发送:
void loop() { HTTPClient http; String jsonPayload = "{\"status\":\"1\"}"; http.begin(wifiClient,"http://192.168.174.71:100/api/StatusReport/AddStatus"); http.addHeader("Content-Type", "application/json"); int httpCode = http.POST(jsonPayload); String payload = http.getString(); Serial.println(httpCode); Serial.println(payload); http.end(); delay(5000); }
2. 完善请求头信息
部分API对Content-Type头的格式要求严格,可以补充字符编码信息:
http.addHeader("Content-Type", "application/json; charset=UTF-8");
同时可以手动添加Content-Length头,确保API能正确识别请求体长度:
String jsonPayload = "{\"status\":\"1\"}"; http.addHeader("Content-Length", String(jsonPayload.length()));
3. 使用ArduinoJson库构造JSON(推荐)
手动拼接JSON极易出错,使用专业的JSON库能确保格式完全符合标准。步骤如下:
- 先在Arduino IDE中安装ArduinoJson库
- 修改代码中的请求体构造部分:
#include <ArduinoJson.h> // 新增头文件 void loop() { HTTPClient http; http.begin(wifiClient,"http://192.168.174.71:100/api/StatusReport/AddStatus"); http.addHeader("Content-Type", "application/json"); // 用ArduinoJson构造JSON DynamicJsonDocument doc(1024); doc["status"] = "1"; String jsonPayload; serializeJson(doc, jsonPayload); int httpCode = http.POST(jsonPayload); String payload = http.getString(); Serial.println(httpCode); Serial.println(payload); http.end(); delay(5000); }
4. 抓包对比请求差异
用抓包工具(如Wireshark)分别抓取手动调用(比如Postman)和ESP8266发送的请求,对比两者的请求头、请求体是否存在差异,比如是否有多余的换行符、空格,或者编码不一致的情况,根据差异调整ESP8266的请求构造。
总结
问题根源是ESP8266发送的请求格式未满足API的校验要求,优先尝试用ArduinoJson库构造JSON,基本能解决大部分格式问题。
内容的提问来源于stack exchange,提问作者yasin
相关产品推荐
相关产品推荐

