ESP32 HTTPS客户端POST请求(跳过证书验证)

ESP32-ESP-IDF-HTTPS客户端

本文例程为ESP32 HTTPS客户端POST请求
只有HTTPS请求部分,联网部分省略默。。。

参考文档

乐鑫ESP-IDF API参考文档

所用API

函数 esp_http_client_init

//启动HTTP链接必须先调用此函数,返回值为为一个结构体对象,也是其它接口的必要参数
//失败返回NULL
//函数参数为constesp_http_client_config_t结构体指针(此结构体用于配置HTTP/HTTPS相关参数)
esp_http_client_handle_t esp_http_client_init(constesp_http_client_config_t *config)

结构体 constesp_http_client_config_t

此结构体用于配置HTTP/HTTPS参数

// 结构体成员如下
typedef struct {
    const char                  *url;//HTTP/HTTPS的url地址
    const char                  *host;//域名或ip(此项可不填)
    int                         port;//请求的端口80或443(默认此项可不填)
    const char                  *username;//用户名用于HTTP身份验证(不用不填)
    const char                  *password;//密码用于HTTP身份验证(不用不填)
    esp_http_client_auth_type_t auth_type;//HTTP身份验证类型默认为HTTP_AUTH_TYPE_NONE即无身份验证(默认即可)
    const char                  *path;//HTTP路径默认为/(客户端无需此项)
    const char                  *query;//HTTP查询
    const char                  *cert_pem;//服务器SSL证书(作为HTTPS服务器时)
    size_t                      cert_len;//证书长度
    const char                  *client_cert_pem;//客户端SSL证书(作为客户端,服务器需要验证证书时)
    size_t                      client_cert_len;//证书长度
    const char                  *client_key_pem;//客户端证书密钥
    size_t                      client_key_len;//密钥长度
    const char                  *client_key_password;//密钥密码
    size_t                      client_key_password_len;//密码长度
    const char                  *user_agent;//要与 HTTP 请求一起发送的用户代理字符串
    esp_http_client_method_t    method;//请求模式默认为HTTP_METHOD_GET即GET方法可根据需要进行修改,也可以默认不填请求时直接调用接口
    int                         timeout_ms;//网络超时时间
    bool                        disable_auto_redirect;//禁用HTTP自动重定向
    int                         max_redirection_count;//最大重定向数,如果为零,则使用默认值
    int                         max_authorization_retries;//接收 HTTP 未授权状态代码时的最大连接重试次数,如果为零,则使用默认值。如果 -1 则禁用授权重试
    http_event_handle_cb        event_handler;//HTTP事件回调函数(重要)
    esp_http_client_transport_t transport_type;//HTTP传输类型使用HTTP时填HTTP_TRANSPORT_OVER_TCP,使用HTTPS时填HTTP_TRANSPORT_OVER_SSL
    int                         buffer_size;//HTTP接收缓冲区大小(一般默认即可)
    int                         buffer_size_tx;//HTTP传输缓冲区大小
    void                        *user_data;//HTTP user_data上下文
    bool                        is_async;//设置异步模式,目前仅支持 HTTPS
    bool                        use_global_ca_store;//
    bool                        skip_cert_common_name_check;//跳过服务器证书 CN 字段的任何验证(注意此处有坑)
    esp_err_t (*crt_bundle_attach)(void *conf);//指向esp_crt_bundle_attach的函数指针。允许使用证书捆绑包进行服务器验证,必须在menuconfig中启用
    bool                        keep_alive_enable;//启用保持活动状态超时
    int                         keep_alive_idle;//保持活动空闲时间。默认值为 5(秒)
    int                         keep_alive_interval;//保持活动间隔时间。默认值为 5(秒)
    int                         keep_alive_count;//保持活动状态数据包重试发送计数。默认值为 3 个计数
    struct ifreq                *if_name;//要通过的数据的接口的名称。使用默认界面而不设置
} esp_http_client_config_t;

设置HTTP/HTTPS请求方法

此接口可以手动设置HTTP请求方式(可以覆盖配置结构体的设置)

//client为esp_http_client_init函数返回的结构体对象
//method为需要设置的请求方式GET填HTTP_METHOD_GET,POST填HTTP_METHOD_POST,还有其它方式不一一列举了,可以去这个枚举类型里面看
//失败返回ESP_ERR_INVALID_ARG
esp_err_t esp_http_client_set_method(esp_http_client_handle_t client, esp_http_client_method_t method)

设置请求头(如果需要的话)

//client为esp_http_client_init函数返回的结构体对象
//key为键,valude为值,例如esp_http_client_set_header(client, "Content-Type", "application/json");
//失败返回ESP_FAIL
esp_err_t esp_http_client_set_header(esp_http_client_handle_t client, const char *key, const char *value)

设置请求内容

此处为POST请求

//client为esp_http_client_init函数返回的结构体对象
//data为传输的数据首地址
//len为数据长度
//失败返回ESP_FAIL
esp_err_t esp_http_client_set_post_field(esp_http_client_handle_t client, const char *data, int len)

发起HTTP/HTTPS请求

此接口默认以阻塞方式发起请求

//client为esp_http_client_init函数返回的结构体对象
//失败返回ESP_FAIL
esp_err_t esp_http_client_perform(esp_http_client_handle_t client)

关闭链接

此函数放在最后调用,功能与esp_http_client_init相反

//client为esp_http_client_init函数返回的结构体对象
//失败返回ESP_FAIL
esp_err_t esp_http_client_cleanup(esp_http_client_handle_t client)

例程

#include "esp_system.h"
#include "esp_tls.h"

#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "freertos/task.h"

static const char *TAG = "APP_HTTP";

#define MAX_HTTP_RECV_BUFFER 512
#define MAX_HTTP_OUTPUT_BUFFER 2048

static esp_err_t _http_event_handler(esp_http_client_event_t *evt)
{
    switch (evt->event_id)
    {
    case HTTP_EVENT_ERROR:
        //当执行过程中出现任何错误时,会发生此事件 
        ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
        break;
    case HTTP_EVENT_ON_CONNECTED:
        // 一旦 HTTP 连接到服务器,就不会执行任何数据交换
        break;
    case HTTP_EVENT_HEADER_SENT:
        // 将所有标头发送到服务器后发生此事件
        break;
    case HTTP_EVENT_ON_HEADER:
        // 在接收从服务器发送的每个标头时发生
        break;
    case HTTP_EVENT_ON_DATA:
        ESP_LOGI(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
        //在此处理HTTP请求返回的数据
        break;
    case HTTP_EVENT_ON_FINISH:
        // 完成 HTTP 会话时发生
        break;
    case HTTP_EVENT_DISCONNECTED:
        // 连接断开时发生此事件
        break;
    }
    return ESP_OK;
}

static void http_rest_with_url(void *post_data)
{
    esp_err_t err;
    esp_http_client_config_t config1 = {
        .url = "https://www.baidu.com",
        .transport_type = HTTP_TRANSPORT_OVER_SSL,
        .skip_cert_common_name_check = true,
        // .port = 443,
        .event_handler = _http_event_handler,
    };
    esp_http_client_handle_t client = esp_http_client_init(&config1);


    // POST请求
    esp_http_client_set_method(client, HTTP_METHOD_POST);
    esp_http_client_set_header(client, "Content-Type", "application/json");
    esp_http_client_set_post_field(client, post_data, strlen(post_data));
    err = esp_http_client_perform(client);
    if (err == ESP_OK)
    {
        ESP_LOGI(TAG, "Status = %d, content_length = %d", esp_http_client_get_status_code(client),
                 esp_http_client_get_content_length(client));
    }
    else
    {
        ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err));
    }
    free(post_data);
    esp_http_client_cleanup(client);
}

填坑

ESP32做为客户端进行HTTPS请求时,如果不需要验证服务器证书也就是想跳过证书验证,
改constesp_http_client_config_t结构体中skip_cert_common_name_check成员是没有效果的。
他只会跳过检查证书的CN而不是CA,不会跳过整个证书验证。
所以如果想跳过证书则需要在menuconfig里面修改ESP-TLS选项,改为默认跳过服务器证书如下图
微信截图_20221128000143.png

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
2022 / 01/ 30: 新版esptool 刷micropython固件指令不是 esptool.py cmd... 而是 esptool cmd... 即可;另外rshell 在 >= python 3.10 的时候出错解决方法可以查看:  已于2022年发布的: 第二章:修复rshell在python3.10出错 免费内容: https://edu.csdn.net/course/detail/29666 micropython语法和python3一样,编写起来非常方便。如果你快速入门单片机玩物联网而且像轻松实现各种功能,那绝力推荐使用micropython。方便易懂易学。 同时如果你懂C语音,也可以用C写好函数并编译进micropython固件里然后进入micropython调用(非必须)。 能通过WIFI联网(2.1章),也能通过sim卡使用2G/3G/4G/5G联网(4.5章)。 为实现语音控制,本教程会教大家使用tensorflow利用神经网络训练自己的语音模型并应用。为实现通过网页控制,本教程会教大家linux(debian10 nginx->uwsgi->python3->postgresql)网站前后台入门。为记录单片机传输过来的数据, 本教程会教大家入门数据库。  本教程会通过通俗易懂的比喻来讲解各种原理与思路,并手把手编写程序来实现各项功能。 本教程micropython版本是 2019年6月发布的1.11; 更多内容请看视频列表。  学习这门课程之前你需要至少掌握: 1: python3基础(变量, 循环, 函数, 常用库, 常用方法)。 本视频使用到的零件与淘宝上大致价格:     1: 超声波传感器(3)     2: MAX9814麦克风放大模块(8)     3: DHT22(15)     4: LED(0.1)     5: 8路5V低电平触发继电器(12)     6: HX1838红外接收模块(2)     7:红外发射管(0.1),HX1838红外接收板(1)     other: 电表, 排线, 面包板(2)*2,ESP32(28)  
ESP32中的POST请求可以通过引入urequests模块并使用该模块中的post函数来实现。首先,需要导入urequests模块,以获取执行HTTP POST请求所需的函数。通过import urequests来引入该模块。然后,使用post函数来发送POST请求并传递相应的参数。具体的代码实现可以参考乐鑫ESP32HTTP POST请求源码修改。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [ESP8266之HTTP请求](https://download.csdn.net/download/weixin_38638002/14031809)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [乐鑫ESP32 https post请求](https://blog.csdn.net/weixin_44244400/article/details/115551627)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [ESP32 MicroPython:HTTP POST请求HTTP GET请求](https://blog.csdn.net/zhazhawoaini/article/details/107007818)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kongbai_w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值