ESP8266与API连接失败问题求助及代码排查
ESP8266 HTTPS请求失败问题修复方案
以下是针对你代码中导致请求失败的核心问题及修复方案:
核心问题分析
- HTTPS证书验证拦截:ESP8266的
WiFiClientSecure默认会严格验证服务器SSL证书,若服务器使用自签名证书或证书链不完整,会直接阻断连接。 - QR数据未URL编码:二维码内容常包含特殊字符(如
&、=、空格等),直接拼接进GET参数会破坏URL结构,导致API无法解析请求。 - 串口数据冗余:串口读取的二维码数据可能包含换行符
\n或回车符\r,这些字符会被带入请求参数,引发错误。
修复后的完整代码
#include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include <WiFiClientSecure.h> #include <ArduinoJson.h> const char* ssid = "*****"; const char* password = "********"; String apiEndpoint = "https://host/api/read_qr_kds"; String raw_data = ""; bool new_data_available = false; // URL编码函数,处理特殊字符 String urlEncode(const String& str) { String encodedStr = ""; const char* chars = str.c_str(); for (int i = 0; chars[i] != '\0'; i++) { if (isAlphaNumeric(chars[i]) || chars[i] == '-' || chars[i] == '_' || chars[i] == '.' || chars[i] == '~') { encodedStr += chars[i]; } else { encodedStr += '%'; encodedStr += String((unsigned char)chars[i], HEX); } } return encodedStr; } void setup() { Serial.begin(9600); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi..."); } Serial.println("Connected to WiFi"); } void loop() { while (Serial.available()) { char input = Serial.read(); // 只保留可打印字符,排除无效控制字符 if (isPrintable(input) || input == '\n') { raw_data += input; } if (input == '\n' && raw_data.length() > 1) { // 去掉末尾的换行、回车等冗余字符 raw_data.trim(); Serial.println(raw_data); sendQRDataToAPI(raw_data); raw_data = ""; new_data_available = true; } } if (new_data_available) { new_data_available = false; } } void sendQRDataToAPI(String data) { if (WiFi.status() == WL_CONNECTED) { Serial.println("WiFi connected, sending request..."); WiFiClientSecure client; HTTPClient https; // 跳过证书验证(测试用,生产环境请替换为导入服务器根证书) client.setInsecure(); // 可选:指定TLS版本,适配服务器要求 // client.setTLSVersion(TLS_v1_2); // 对QR数据进行URL编码,避免特殊字符破坏请求结构 String encodedData = urlEncode(data); String link = apiEndpoint + "?raw_data=" + encodedData; Serial.println("Request URL: " + link); https.begin(client, link); https.setTimeout(10000); int httpCode = https.GET(); if (httpCode == HTTP_CODE_OK) { Serial.println("Request successful!"); String response = https.getString(); Serial.println("API Response: " + response); StaticJsonDocument<512> doc; DeserializationError error = deserializeJson(doc, response); if (!error) { int orderId = doc["qrData"]["OrderID"]; Serial.print("OrderID: "); Serial.println(orderId); const char* status = doc["status"]; Serial.print("Status: "); Serial.println(status); } else { Serial.print("JSON parse failed: "); Serial.println(error.c_str()); } } else { Serial.print("Request failed, code: "); Serial.println(httpCode); Serial.println(https.errorToString(httpCode)); } https.end(); } else { Serial.println("WiFi disconnected, can't send data."); } }
关键修改说明
- URL编码处理:确保二维码中的特殊字符不会破坏URL结构,API能正确解析参数。
- 证书验证跳过:快速排查证书问题,生产环境建议使用
client.setCACert()导入服务器根证书以提升安全性。 - 串口数据清洗:用
trim()去掉数据末尾的冗余换行、回车符,避免无效参数传入。 - 调试信息增强:输出更清晰的状态提示,方便快速定位问题。
内容的提问来源于stack exchange,提问作者jack
相关产品推荐
相关产品推荐

