ESP32 Arduino HTTPS 的研究

在物联网获得数据的过程中,HTTP 和 HTTPS 还是有蛮大区别的。

  1. 可以使用下面的Curl 命令测试
curl -X POST https://httpbin.org/post -H "Content-Type: application/json" -d '{"name": "test", "value": "123"}'

返回值

{
  "args": {},
  "data": "{name: test, value: 123}",
  "files": {},
  "form": {},
  "headers": {
    "Accept": "*/*",
    "Content-Length": "24",
    "Content-Type": "application/json",
    "Host": "httpbin.org",
    "User-Agent": "curl/8.7.0",
    "X-Amzn-Trace-Id": "Root=1-69ddf67f-75016f90629ad2556d1387f1"
  },
  "json": null,
  "origin": "117.143.53.223",
  "url": "https://httpbin.org/post"
}

2.编写 ESP32 Arduino 代码

#include <WiFi.h>
#include <WiFiClientSecure.h>

// 设置 Wi-Fi 凭据, 
const char* ssid = "你的 WIFI 名称";
const char* password = "对应的密码";

// 目标服务器信息
const char* server = "httpbin.org"; // 域名
const int port = 443; // HTTPS 默认端口
const char* path = "/post"; // 请求路径

// 创建安全客户端对象
WiFiClientSecure client;

void setup() {
  Serial.begin(115200);
  delay(1000);

  // 连接 Wi-Fi
  Serial.println("正在连接 Wi-Fi...");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nWi-Fi 连接成功!");
  Serial.print("IP 地址: ");
  Serial.println(WiFi.localIP());

  // 设置 HTTPS 客户端(跳过证书验证,仅用于测试)
  client.setInsecure(); // 注意:生产环境中应使用证书验证

  // 发送 POST 请求
  sendPostRequest();
}

void loop() {
  // 主循环为空,仅执行一次请求
}

void sendPostRequest() {
  Serial.println("正在连接服务器...");
  if (!client.connect(server, port)) {
    Serial.println("连接服务器失败!");
    return;
  }
  Serial.println("服务器连接成功!");

  // 构建 POST 请求数据(JSON 格式)
  String postData = "{\"name\":\"test\",\"value\":\"123\"}";

  // 构建 HTTP 请求头
  String request = "POST " + String(path) + " HTTP/1.1\r\n";
  request += "Host: " + String(server) + "\r\n";
  request += "Content-Type: application/json\r\n";
  request += "Content-Length: " + String(postData.length()) + "\r\n";
  request += "Connection: close\r\n\r\n"; // 关闭连接
  request += postData;

  // 发送请求
  Serial.println("发送 POST 请求...");
  client.print(request);
  Serial.println("请求已发送!");

  // 等待并读取响应
  Serial.println("服务器响应:");
  unsigned long timeout = millis();
  while (client.connected() || client.available()) {
    if (client.available()) {
      String line = client.readStringUntil('\n');
      Serial.println(line);
    }
    // 超时处理
    if (millis() - timeout > 5000) {
      Serial.println("响应超时!");
      break;
    }
  }

  // 断开连接
  client.stop();
  Serial.println("连接已关闭。");
}

运行结果串口输出如下:

请求已发送!
服务器响应:
HTTP/1.1 200 OK

Date: Tue, 14 Apr 2026 08:21:05 GMT

Content-Type: application/json

Content-Length: 412

Connection: close

Server: gunicorn/19.9.0

Access-Control-Allow-Origin: *

Access-Control-Allow-Credentials: true



{
  "args": {}, 
  "data": "{\"name\":\"test\",\"value\":\"123\"}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Content-Length": "29", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "X-Amzn-Trace-Id": "Root=1-69ddf8f1-007fb8cc07ce50765cddb2f1"
  }, 
  "json": {
    "name": "test", 
    "value": "123"
  }, 
  "origin": "117.143.53.223", 
  "url": "https://httpbin.org/post"
}
[  7009][E][ssl_client.cp

另外一个例子,看起来更容易理解一些:

#include <WiFi.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>

// WiFi凭据
const char* ssid = "your_wifi_ssid";
const char* password = "your_wifi_password";

void setup() {
  Serial.begin(115200);
  
  // 连接WiFi
  WiFi.begin(ssid, password);
  Serial.print("连接WiFi");
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  
  Serial.println();
  Serial.println("WiFi连接成功!");
  Serial.print("IP地址: ");
  Serial.println(WiFi.localIP());
  
  // 发送HTTPS POST请求
  sendHttpsPostRequest();
}

void loop() {
  // 空循环
}

void sendHttpsPostRequest() {
  // 创建WiFiClientSecure对象用于HTTPS
  WiFiClientSecure *client = new WiFiClientSecure;
  
  if(client) {
    // 设置为不验证SSL证书(用于测试,生产环境建议验证证书)
    client->setInsecure();
    
    // 或者如果你想验证证书,可以设置根CA证书
    // client->setCACert(rootCACertificate);
    
    HTTPClient https;
    
    Serial.println("[HTTPS] 开始连接...");
    
    if (https.begin(*client, "https://httpbin.org/post")) {
      Serial.println("[HTTPS] 连接成功");
      
      // 设置HTTP头
      https.addHeader("Content-Type", "application/json");
      https.addHeader("Token", "abc");
      
      // 准备JSON数据
      String jsonPayload = "{\"cityCode\":\"310100\",\"isGetStopArrive\":\"1\",\"lon\":\"121.3747863\",\"lat\":\"31.11027359\",\"limit\":20,\"offset\":0,\"coordinateType\":1}";
      
      Serial.println("发送HTTPS POST请求到: https://httpbin.org/post");
      Serial.println("请求头: Token=abc");
      Serial.println("请求体: " + jsonPayload);
      
      // 发送POST请求
      int httpResponseCode = https.POST(jsonPayload);
      
      if (httpResponseCode > 0) {
        String response = https.getString();
        Serial.println("HTTPS响应代码: " + String(httpResponseCode));
        Serial.println("响应内容:");
        Serial.println(response);
      } else {
        Serial.println("HTTPS请求失败");
        Serial.println("错误代码: " + String(httpResponseCode));
        Serial.println("错误信息: " + https.errorToString(httpResponseCode));
      }
      
      // 关闭连接
      https.end();
    } else {
      Serial.println("[HTTPS] 无法连接");
    }
    
    // 删除客户端对象
    delete client;
  } else {
    Serial.println("无法创建WiFiClientSecure客户端");
  }
}

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注