ESP32向带POST路由网站发送HTTPS POST请求遇阻,求排查
排查ESP32通过HTTPS POST发送传感器数据的问题
我正在开发一个项目,需要将传感器读数发送至网站进行绘图展示。最初使用原生HTTPClient模块搭配WiFiClient发送POST请求但无法正常工作,经查询得知需使用支持HTTPS的WiFiClientSecure库。修改代码后仍无法正常运行,以下是相关代码及排查建议:
初始HTTPClient代码(无法处理HTTPS)
#include <WiFi.h> #include <HTTPClient.h> const char* ssid = "dssdf"; // Enter SSID here const char* password = "skdjfh";//.. password //const char* serverName = "monitor.com"; //Domain name with URL path or IP address with path const char* serverName = "https://...../post_data"; unsigned long lastTime = 0; unsigned long timerDelay = 2000; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); Serial.println("Connecting"); while(WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("Connected to WiFi network with IP Address: "); Serial.println(WiFi.localIP()); Serial.println("Timer set to 5 seconds (timerDelay variable), it will take 5 seconds before publishing the first reading."); } void loop() { if ((millis() - lastTime) > timerDelay) { //Check WiFi connection status if(WiFi.status()== WL_CONNECTED){ WiFiClient client; HTTPClient http; // Domain name with URL path or IP address with path http.begin(client, serverName); // Specify content-type header http.addHeader("Content-Type", "text/plain"); // Data to send with HTTP POST String httpRequestData = "103"; int httpResponseCode = http.POST(httpRequestData); Serial.print("HTTP Response code: "); Serial.println(httpResponseCode); // Free resources http.end(); } else { Serial.println("WiFi Disconnected"); } lastTime = millis(); } }
修改后的WiFiClientSecure代码片段
const char* path = "/post_data"; // the SHA-1 fingerprint of the website's SSL certificate const char fingerprint[] PROGMEM = "b2....................B"; void setup() { ............; Serial.println("Connected to Wi-Fi"); } void loop() { // Wait for the Wi-Fi connection to be established if (WiFi.status() == WL_CONNECTED) { // Use WiFiClientSecure class to create TLS connection WiFiClientSecure client; if (client.verify(fingerprint, host)) { // Connect to the server if (client.connect(host, 3000)) { Serial.println("Connected to server"); // Construct the POST request String data = "123"; String request = "POST " + String(path) + " HTTP/1.1\n" + "Host: " + String(host) + "\n" + "Content-Type: application/x-www-form-urlencoded\n" + "Content-Length: " + String(data.length()) + "\n" + "\n" +data; // Send the POST request client.print(request); // Wait for the server to respond while (client.connected()) { String line = client.readStringUntil('\n'); if (line == "\r") { Serial.println("Response headers received"); break; } } // Read and print the response body while (client.available()) { String line = client.readStringUntil('\n'); Serial.println(line); } // Close the connection client.stop(); Serial.println("Connection closed"); } else { Serial.println("Connection failed"); } } else { Serial.println("certificate doesn't match"); } } else { Serial.println("Wi-Fi not connected"); } delay(10000); }
核心排查点与修复建议
1. 端口号错误
HTTPS协议默认端口是443,你代码中使用的3000是非标准端口,除非服务器明确配置了该端口作为HTTPS入口,否则必须改为443。
2. 证书指纹问题
- 确保指纹是目标网站SSL证书的SHA-1格式(共40个字符),注意大小写和字符完整性,指纹不匹配会直接触发
certificate doesn't match提示。 - 临时测试可添加
client.setInsecure();跳过指纹验证(正式环境禁止使用,存在安全风险),确认是否是证书验证导致的连接失败。
3. HTTP请求格式错误
HTTP协议要求用\r\n作为换行符,你代码中用的\n会导致服务器无法正确解析请求头,需将所有换行替换为\r\n。同时建议添加Connection: close头,避免连接长时间占用资源。
4. 变量未定义问题
代码片段中host变量未定义,需补充:
const char* host = "你的服务器域名"; // 例如 monitor.com
5. 串口调试定位
根据串口输出信息精准定位:
- 若输出
certificate doesn't match:重新获取证书指纹,或检查证书是否过期/更换。 - 若输出
Connection failed:检查端口、域名解析、服务器可用性,或用client.connectError()打印具体错误码。 - 若连接成功但无预期响应:用Postman/curl测试服务器接口是否正常,确认请求格式与服务器要求匹配。
修正后的完整参考代码
#include <WiFi.h> #include <WiFiClientSecure.h> const char* ssid = "dssdf"; const char* password = "skdjfh"; const char* host = "monitor.com"; const char* path = "/post_data"; const char fingerprint[] PROGMEM = "b2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxB"; unsigned long lastTime = 0; const unsigned long timerDelay = 10000; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); Serial.println("Connecting to WiFi..."); while(WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\nConnected to WiFi, IP: " + WiFi.localIP().toString()); } void loop() { if ((millis() - lastTime) > timerDelay) { if(WiFi.status() == WL_CONNECTED) { WiFiClientSecure client; // 临时测试用,正式环境删除 // client.setInsecure(); if (client.verify(fingerprint, host)) { Serial.println("Certificate verified"); if (client.connect(host, 443)) { Serial.println("Connected to server"); String data = "123"; // 替换为传感器读数 String request = "POST " + String(path) + " HTTP/1.1\r\n" + "Host: " + String(host) + "\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n" + "Content-Length: " + String(data.length()) + "\r\n" + "Connection: close\r\n" + "\r\n" + data; client.print(request); // 读取响应头 while (client.connected()) { String line = client.readStringUntil('\n'); if (line == "\r") { Serial.println("\nResponse headers:"); break; } Serial.println(line); } // 读取响应体 Serial.println("Response body:"); while (client.available()) { String line = client.readStringUntil('\n'); Serial.println(line); } client.stop(); Serial.println("Connection closed"); } else { Serial.println("Failed to connect to server"); Serial.print("Error code: "); Serial.println(client.connectError()); } } else { Serial.println("Certificate verification failed"); } } else { Serial.println("WiFi disconnected, reconnecting..."); WiFi.reconnect(); } lastTime = millis(); } }
内容的提问来源于stack exchange,提问作者kisuke_urahara
相关产品推荐
相关产品推荐

