ESP8266 NodeMcu在Arduino环境下请求API数据失败,无正常串口输出
ESP8266 NodeMcu 连接WiFi后API请求无预期输出问题排查
提问背景
- 硬件采用ESP8266 NodeMcu开发板,配套开发IDE为Arduino
- 开发目标为实现开发板连接WiFi后发起API请求拉取目标接口数据,将解析后的结果输出至串口监视器
- 已在该问题上耗时10小时未定位根因,现有现象为开发板无法按预期获取目标API数据、串口无对应解析结果输出,存有串口监视器报错记录可辅助排查
- 现有实现代码如下:
#include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include <ArduinoJson.h> //填写个人WiFi凭据 const char* ssid = "Kyzer"; const char* password = "@kyzer4$"; //用于存储服务器响应的字符串 String response = ""; //JSON文档对象 DynamicJsonDocument doc(2048); void setup() { Serial.begin(115200); //初始化WiFi连接 WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); Serial.println(""); //等待WiFi连接完成 while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.print("WiFi已连接,设备IP地址: "); Serial.println(WiFi.localIP()); } void loop() { //初始化HTTP客户端 HTTPClient http; //目标API地址 String request = "https://covid-api.mmediagroup.fr/v1/cases?country=Portugal"; //发起HTTP请求 http.begin(request); //使用HTTP GET请求方法 http.GET(); //获取服务器返回的响应内容 response = http.getString(); //解析JSON数据,捕获解析异常 DeserializationError error = deserializeJson(doc, response); if(error) { Serial.print(F("deserializeJson() 执行失败: ")); Serial.println(error.f_str()); delay(5000); return; } //在串口监视器打印解析得到的数值 Serial.print("确诊病例数: "); Serial.println(doc["confirmed"].as<int>()); Serial.print("治愈数: "); Serial.println(doc["recovered"].as<int>()); Serial.print("死亡数: "); Serial.println(doc["deaths"].as<int>()); Serial.println(""); //关闭HTTP连接 http.end(); //间隔5秒后进入下一次循环 delay(5000); }
故障原因及修复方案
以下问题均可直接导致代码运行不符合预期,建议按顺序逐一排查
- HTTPS请求未配置基础校验逻辑
ESP8266发起HTTPS请求时默认开启根证书校验,当前代码直接传入HTTPS地址调用http.begin(),既没有配置对应站点的根证书,也没有开启跳过校验的开关,会导致请求被系统直接拦截,无法获取正常响应。
修复:在http.begin()前增加http.setInsecure()语句跳过证书校验,先验证基础网络连通性,后续可根据安全需求替换为正式的证书校验配置。 - 未校验HTTP请求返回状态码
当前代码调用http.GET()后直接读取响应内容,没有对返回状态码做判断。遇到跨域拦截、接口失效、服务器错误等场景时,http.getString()会返回空值或非JSON格式的错误提示内容,直接传入JSON解析流程会触发解析中断。
修复:GET请求返回后增加状态码判断逻辑,仅当返回码为200时进入JSON解析流程,其余场景直接打印状态码和错误信息。 - JSON解析路径与接口实际结构不匹配
目标接口的返回数据为嵌套结构,不存在顶层的confirmed/recovered/deaths字段,相关统计数值实际嵌套在All子对象下,直接读取顶层字段会返回空值,表现为串口打印的统计值全部为0。
修复:调整JSON取值路径为doc["All"]["confirmed"].as<int>(),匹配接口实际返回结构。 - 全局JSON文档对象未做缓存清理
当前代码中doc为全局对象,每次循环解析新响应时未调用doc.clear()清空上一次的解析缓存,多次循环后会触发内存溢出、解析失败问题。
修复:在每次调用deserializeJson()前增加doc.clear()语句清空缓存。 - WiFi连接逻辑无超时保护
当前代码的WiFi等待连接循环没有超时判断,遇到密码错误、信号强度不足等场景时,程序会永久卡在连接循环中,无法进入后续HTTP请求流程。
修复:增加WiFi连接超时计数,超时后打印错误信息并触发设备重启。
内容的提问来源于stack exchange,提问作者sentrax
相关产品推荐
相关产品推荐

