通用步骤

[English]

本文档总结了 ESP-IDF 中 HTTP 协议的通用实现流程,涵盖协议基础说明及结构体配置方法。

通过掌握本文档内容,开发者能够快速理解协议关键逻辑,为后续示例学习提供统一参考。

HTTP/HTTPS 协议

HTTP(超文本传输协议)是一种应用层协议,用于客户端(如浏览器或移动应用)与服务器之间传输超文本及其他资源。它是万维网的核心通信机制。HTTPS(HTTP Secure)则是在 HTTP 基础上,通过 TLS/SSL(传输层安全协议/安全套接字层)实现数据加密和身份验证的安全版本。

协议模型

HTTP/HTTPS 基于请求-响应模型。在一次完整的通信过程中:

  • 客户端发送 请求,请求由几个部分组成:

    • 请求方法:表示操作类型,例如 GET 用于获取资源,POST 用于提交数据。

    • URL:统一资源标识符,用于标识互联网上的某个资源,例如网页地址。

    • 请求头:包含附加信息,如数据类型、认证信息等。

    • 请求体:可选部分,用于携带要传递给服务器的数据,例如表单内容或 JSON 数据。

  • 服务器处理请求后返回 响应,响应包括:

    • 状态码:用三位数字表示处理结果,例如 200 表示成功,404 表示资源未找到,500 表示服务器错误。

    • 响应头:包含响应的属性信息,例如数据长度或数据格式。

    • 响应体:实际返回的资源内容,例如网页 HTML 文本或 API 返回的 JSON 数据。

协议特性

HTTP 协议具有无状态性。这意味着服务器不会自动保存客户端的请求历史,每次请求都被视为独立的事件。为了实现“记住用户”的功能,需要借助 Cookie(一种存储在客户端的小型数据文件)、Session(基于服务器端的会话管理机制)或 Token(令牌,用于标识和验证用户身份)等方式。

HTTPS 在此基础上引入 TLS/SSL 加密。通过加密通信,客户端和服务器之间的数据即使被第三方截获,也无法被轻易解析。同时,TLS/SSL 还提供身份认证,确保通信对象是可信的服务器和完整性校验,保证数据未被篡改,从而显著提升安全性。

常见应用场景

HTTP/HTTPS 广泛应用于:

  • 网页浏览:浏览器请求网页,服务器返回 HTML、CSS、图片等资源。

  • API 调用:客户端应用调用 RESTful API 与服务器交换 JSON 或 XML 数据。

  • 文件传输:上传表单、下载图片或固件文件。

HTTP/S 客户端执行流程

在 ESP32 上使用 HTTP/S 客户端时,其标准执行流程可概括为以下步骤:

  1. 配置结构体:详细说明可参考 结构体配置

  2. 应用结构体配置

  • 调用 esp_http_client_init() 创建 HTTP/S 客户端实例,并将配置结构体应用到客户端对象中。相关使用及参数说明可参考 ESP HTTP 客户端 API

  1. 发起请求:详细说明可参考 发起请求

  2. 获取响应:必须获取 HTTP/S 状态码和响应体长度,用于准确判断请求的执行结果与数据范围。响应体内容的获取可根据应用需求灵活选择,可通过事件回调、流式读取或一次性完整读取实现。

  • 调用 esp_http_client_get_status_code() 获取 HTTP/S 状态码,若返回 200,表示请求成功。相关使用及参数说明可参考 ESP HTTP 客户端 API

  • 调用 esp_http_client_get_content_length() 获取响应体长度。相关使用及参数说明可参考 ESP HTTP 客户端 API

  • 调用 esp_http_client_read_response() 获取响应体。相关使用及参数说明可参考 ESP HTTP 客户端 API

  1. 释放资源

  • 调用 esp_http_client_cleanup() 释放 HTTP/S 客户端占用的资源,避免内存泄漏。调用后,该客户端句柄不再可用。相关使用及参数说明可参考 ESP HTTP 客户端 API

结构体配置

在 ESP-IDF 中,HTTP 客户端通过 esp_http_client_config_t 结构体进行配置,用于定义客户端的目标地址、请求行为、安全认证以及扩展功能。结构体提供从基础 HTTP/S 请求到高级安全、性能优化和扩展能力的完整配置。实际应用中应根据请求目标、通信安全性、数据量和网络环境合理选择各类参数,以实现稳定、高效、安全的 HTTP 通信。具体结构体成员可参考 ESP HTTP 客户端 API

目标服务器配置

用于指定 HTTP/HTTPS 请求的目标地址和访问方式:

URL 配置

  • 可以通过完整 URL 配置客户端。URL 的优先级最高,会覆盖其他相关字段,适用于固定请求地址的场景。

  • 也可通过分字段配置实现动态拼接路径或查询参数,适合需要根据运行时条件生成请求的场景。

    • query:在 HTTP/S 请求中,查询参数是附加在 URL 路径后的一段字符串,用于向服务器传递额外信息或请求条件,通常紧跟在路径之后,用 ? 连接。

      • 查询参数常用于 GET 请求中,用来传递条件、关键字、分页信息或其它附加数据,告诉服务器客户端希望获取的数据范围、特定资源或处理方式;同时也可用于指定资源标识,因为某些接口通过查询参数定位具体资源,而不是放在路径中;还可以携带控制信息,如用户状态、过滤条件或其它自定义参数,帮助服务器返回更精确的结果。

      • 在 POST、PUT、DELETE 等请求中,也可以使用查询参数传递辅助信息或定位资源,但主要数据通常放在请求体中。

      • 使用 host + path 配置方式时,如果接口需要查询参数,就必须通过 query 设置;使用完整 URL 配置时,查询参数可以直接包含在 URL 中,无需单独设置。

      • 当查询参数包含空格、特殊符号或非 ASCII 字符时,必须进行 URL 编码,以保证请求合法且服务器能正确解析。

地址类型:支持 IPv4/IPv6/域名等,可通过 addr_type 指定。

认证与安全配置

支持 HTTP 层身份验证和 TLS/SSL 安全机制,包括用户名/密码认证、服务器证书验证、客户端证书及私钥配置、TLS 协议版本选择,以及可选的硬件安全扩展,如 ECDSA 外设安全元件。在访问启用认证的服务时,必须正确配置相关信息。

HTTPS 场景下,服务器证书验证是保证通信安全的必要措施;客户端证书用于双向认证;硬件安全配置适用于高安全性应用,可加强密钥管理和加密操作的安全性。

根证书 (Root CA Certificate)是由受信任的证书颁发机构(CA)签发的数字证书,用于建立 TLS/SSL 安全通信中的信任链。在 HTTPS 或其他基于 TLS/SSL 的协议中,服务器会提供其证书,客户端(如 ESP32)通过根证书验证服务器身份,以确保通信对象的合法性,防止数据被篡改或伪造。

根证书的主要作用包括:

  1. 服务器身份验证:确认服务器证书的有效性和可信来源。

  2. 安全通信基础:在验证通过后建立加密通道,保证数据在传输过程中不被窃听。

  3. 防范中间人攻击:防止恶意节点伪装服务器截取或篡改数据。

服务器证书验证 用于确保客户端访问的 HTTPS 服务器身份可信。客户端通过验证服务器提供的证书与受信任的根证书是否匹配,确认服务器确实是预期的目标,而非中间人攻击或伪造服务器。这一验证不仅保证了通信对象的真实性,还确保通过 TLS/SSL 加密传输的数据在传输过程中未被篡改,从而保护数据的机密性和完整性。根证书可通过以下两种方式配置:

  • cert_pem 用于指定单个或少量 PEM 格式的根证书,使用灵活但管理量大,适合针对特定服务器或自签名证书的场景,需要开发者手动提供证书内容。如果访问的是私有服务器或需要固定信任特定证书,则必须使用这种方式。

  • crt_bundle_attach

    • 预编译好的证书捆绑(bundle),包含多个常用根证书,客户端可以同时验证多种常见 HTTPS 服务器证书,无需单独提供每个证书。

    • 适合通用场景或需要访问多个 HTTPS 服务器的应用,减少手动管理证书的工作量。如果访问的是公开 HTTPS 服务,通常可以直接使用这种方式。

    • 通常可以通过调用 esp_crt_bundle_attach 获取。相关使用说明可参考 ESP 证书包

认证机制配置 用于指定客户端在 HTTP 层如何进行身份认证,主要涉及认证类型选择(如 Basic 认证Digest 认证)和认证失败后的重试次数。相关结构体成员说明如下:

  • auth_type 用于显式指定客户端采用的身份认证方式(如 Basic 或 Digest),适用于需要固定认证方式或避免多余协商的场景。

  • max_authorization_retries 用于控制认证失败后的最大重试次数,适合需要限制或关闭自动重试的场景。如该参数未指定,客户端将使用默认重试次数(通常由库内部设定);若指定为 -1,则禁用自动重试,客户端在收到 401 响应后不会再次发送带认证信息的请求,需要开发者手动处理后续认证请求。

请求行为配置

控制请求方法、网络超时、缓冲区大小、自动重定向、授权重试和异步模式等行为。

缓冲区 需匹配预期数据量以防数据截断;

异步模式 可用于不阻塞主任务的应用,进一步说明可参考 异步请求

  • is_async 用于指定客户端是否启用异步模式。默认为同步模式,及不启用,设置为 true 时表示启用。

  • timeout_ms 用于设置请求的超时时间(毫秒),表示客户端等待服务器响应的最大时间,防止长时间等待导致任务阻塞或资源占用。如果请求超过该时间仍未完成,esp_http_client_perform() 会返回超时错误。

自定义传输选项 可满足特殊网络需求,如代理或加密通道。

会话与连接保持配置

用于优化连接性能,包括 keep-alive 和 TLS 会话复用。

  • 启用 keep-alive 可减少重复连接开销,但需服务端支持;

  • TLS 会话复用 可降低握手消耗,提高 HTTPS 通信效率。

参数选择应结合连接频率和系统资源情况。

事件与上下文配置

提供事件回调和用户自定义上下文,用于处理请求过程中的数据和状态信息。

  • 事件回调 用于实现必要处理逻辑,用户数据指针在请求期间必须保持有效,以确保数据安全和一致性。

此类配置适用于实时数据处理、OTA 升级和调试日志等场景。

网络与扩展配置

支持多网络接口、HTTP/2 协议及自定义传输:

  • 可通过指定网络接口控制请求路径;

  • 使用 ALPN 协议实现 HTTP/2 协商;

  • 通过自定义 transport 满足特殊网络需求。

配置时需确保与服务端和客户端接口兼容,以避免握手或传输异常。

请求操作说明

HTTP 请求操作指客户端向服务器发起的不同类型请求,每种请求操作对应不同的动作和服务器处理逻辑。在 ESP-IDF HTTP 客户端中,这些请求操作本质上通过 esp_http_client_config_t 结构体中的的 method 参数指定。ESP-IDF 中支持的所有请求操作可参考 esp_http_client_method_t 结构体的 成员。以下仅选取部分进行说明。

请求操作

请求操作

作用

典型使用场景

GET

请求获取资源,服务器返回资源内容

读取网页、获取 JSON 数据、下载文件

POST

向服务器提交数据,通常会触发服务器的创建或更新操作

表单提交、上传数据、API 调用

PUT

更新服务器上的资源(有时也可创建)

修改已有数据或文件

DELETE

删除服务器上的资源

删除数据库记录、文件等

HEAD

与 GET 类似,但服务器只返回响应头,不返回主体

检查资源是否存在、获取元信息

PATCH

对部分服务器资源进行修改

修改部分字段的数据,不覆盖整个资源

在 ESP-IDF 中,所有 HTTP 请求操作在客户端代码上的执行流程核心相同,但在细节上存在部分差异:

  1. 设置 method

  • 调用 esp_http_client_set_method() 设置请求方法。相关使用及参数说明可参考 ESP HTTP 客户端 API

  • GET 为默认请求方法,所以如果没有显式调用该 API,客户端将会使用 GET 方法发送请求。

  • 虽然可以在结构体初始化时配置 .method 成员,但请求方法可能在同一客户端实例上多次变化,初始化结构体固定 .method 不够灵活,每次修改仍需调用 API,因此在实际应用中,初始化结构体通常只配置固定参数(URL、回调、超时等),method 和动态请求参数通过 API 设置。

  1. 配置数据

  • 调用 esp_http_client_set_post_field() 设置请求体,用于携带实际数据,是客户端发送给服务器的负载。相关使用及参数说明可参考 ESP HTTP 客户端 API

  • 调用 esp_http_client_set_header() 设置请求头,用于传递元信息,例如身份验证、数据类型、缓存控制、接口自定义信息,告知服务器如何解析请求体或进行身份验证。相关使用及参数说明可参考 ESP HTTP 客户端 API

  • 调用 esp_http_client_set_user_data() 设置用户数据,可在回调中访问,用于保存状态信息、上下文数据或与应用逻辑相关的自定义信息。相关使用及参数说明可参考 ESP HTTP 客户端 API

  • 并非所有请求都需要配置以上内容,可根据实际情况配置对应内容:

请求操作

请求体要求

请求头要求

说明

GET

不使用

可选

GET 请求用于获取资源,无需请求体,请求头可根据接口需要设置,例如 Authorization、Accept。

POST

通常必须使用

必须指定数据类型

POST 用于创建资源或提交数据;请求体携带数据,请求头指明数据类型和可能的身份验证信息。

PUT

通常必须使用(部分接口可选)

如果设置了请求体则必须指定数据类型

PUT 用于完全更新资源;如果接口需要上传数据,则需要设置请求体,并通过请求头告知服务器数据类型。

DELETE

可选

可选

DELETE 请求用于删除资源;一般不需要请求体,但部分接口允许附加数据,请求头可根据接口需求设置。

HEAD

不使用

可选

HEAD 请求只返回响应头;无请求体,请求体可用于身份验证或自定义信息。

PATCH

必须使用

必须指定数据类型

PATCH 用于部分更新资源;请求体必须包含要修改的数据字段,并通过请求头指明数据格式。

  1. 执行请求:在 ESP-IDF 中,HTTP 客户端支持两种请求执行方式:一次性传输与流式传输。

一次性传输 是最常见的方式,通过调用 esp_http_client_perform() 完成整个 HTTP 请求与响应过程。在该模式下,ESP-IDF 内部会自动完成连接、发送请求、接收响应体以及关闭连接等步骤,应用程序仅在请求完成后获取最终结果。其特点是使用简单,但需要一次性缓存完整响应体,仅适合响应内容较小的场景。相关使用及参数说明可参考 ESP HTTP 客户端 API

流式传输 允许开发者分段读取响应体,可以在接收数据的过程中边读取边处理,而无需一次性存放完整响应体。这种方式更灵活,适合大文件下载、长连接、内存受限的场景。其执行流程相较于一次性传输更为复杂:

  • 调用 esp_http_client_open() 发起请求并建立连接。相关使用及参数说明可参考 ESP HTTP 客户端 API

  • 调用 esp_http_client_fetch_headers() 获取响应头。相关使用及参数说明可参考 ESP HTTP 客户端 API

  • 多次调用 esp_http_client_read() 读取响应体,需要自行构建循环,每次读取一部分数据,直至完整响应体被读取完。相关使用及参数说明可参考 ESP HTTP 客户端 API

  • 处理完成后调用 esp_http_client_close() 关闭连接。相关使用及参数说明可参考 ESP HTTP 客户端 API

分块传输编码

概述

分块传输编码是 HTTP/1.1 支持的一种服务器数据的传输机制。当服务器在响应头中没有声明 Content-Length,且响应长度在发送时无法预先确定时,通常采用该编码以保持连接并逐块发送数据。

在该机制下,响应主体被拆分为一系列分块(chunk)逐次发送。每个分块前包含其长度标识,客户端在接收时按块解析,直到遇到长度为零的块表示传输结束。主要应用场景包括:

  • 响应内容长度在生成时无法预先确定,例如流式数据、动态计算结果或持续推送的日志信息。

  • 需要边生成边传输数据,以降低响应延迟或提升实时性。

  • 大数据量传输场景中,为避免一次性缓存和发送全部内容,提高内存和网络利用效率。

分块传输编码的优势在于灵活且支持流式输出,无需服务端提前计算总长度,客户端可逐步处理数据,适合内存受限或需即时处理的应用。缺点是增加解析复杂度和协议开销,每个分块需携带长度信息;同时部分调试和验证工具对分块响应支持有限,调试和问题定位较为复杂。

增量重分配策略

在客户端处理响应时,如果无法预先获得完整响应长度,通常需要使用增量重分配策略:

  • 初始分配一个较小缓冲区用于接收数据。

  • 每次接收到新的数据块时,根据当前已接收数据量动态扩展缓冲区大小。

  • 通过 realloc() 或等效方式重新分配内存,并将已有数据拷贝到新缓冲区,再追加新数据。

  • 重复以上过程直到整个响应接收完成。

增量重分配策略可以应用于所有未知长度的响应,而不仅限于 chunked 编码场景。

执行逻辑

编码判断:客户端调用 esp_http_client_is_chunked_response(),通过其返回值判断当前收到的 HTTP 响应是否使用 chunk 编码。相关使用及参数说明可参考 ESP HTTP 客户端 API返回值处理

  • 如果返回 true,表示响应数据采用了 chunked 编码,客户端无法预先知道总长度,需要使用增量重分配策略或逐块处理数据。

  • 如果返回 false,表示客户端可以通过 Content-Length 获取响应总长度,一次性分配缓冲区。

重定向与状态码

在 HTTP 协议中,重定向是一种服务器指令,用于通知客户端请求的资源已移动或需要进一步操作。其实现方式通常是通过服务器返回 3xx 系列状态码(范围 300–399),并在响应头中附带 Location 字段,指示新的访问地址。

例如,当用户请求 http://example.com 时,服务器可能返回一个 301(Moved Permanently) 状态码,表示所请求的资源已被永久移动,并在 Location 字段中指定 https://example.com,提示客户端改用新的 HTTPS 地址访问。

重定向类型

重定向的具体类型取决于服务器端的实现。服务器可在 Location 中返回相对路径或绝对路径:

相对路径重定向

  • Location 值为相对路径,例如 /new-path

  • 客户端在处理时会以当前请求的主机名和协议为基础,拼接生成完整的新 URL,若拼接逻辑出错,可能导致访问失败。

  • 该类型的重定向依赖于原始请求的 URL,服务器只需给出相对路径,适合在同一域名下的资源迁移。

绝对路径重定向

  • Location 值为完整的绝对 URL,例如 http://example.com/new-path

  • 客户端可直接使用该 URL 发起新的请求,无需拼接。

  • 该类型的重定向与原始请求无关,可以重定向到不同的域名或协议,灵活性更高,但返回报文长度更长,占用更多带宽。

重定向处理

在 ESP-IDF 的 HTTP 客户端中,当服务器返回 3xx 响应时,会触发 HTTP_EVENT_REDIRECT 回调事件。开发者可以在回调中执行以下操作:

  • 修改请求头:调用 esp_http_client_set_header() 增加或修改请求头字段,例如添加用户认证信息或特定标识。相关使用及参数说明可参考 ESP HTTP 客户端 API

  • 显示触发重定向 :调用 esp_http_client_set_redirection() 指示客户端按照响应头 Location 字段中提供的新 URL 发起后续请求。相关使用及参数说明可参考 ESP HTTP 客户端 API

  • 控制自动重定向行为:通过配置 esp_http_client_config_t 结构体中的部分相关成员控制自动重定向行为。

    • disable_auto_redirect 用于决定客户端收到 3xx 状态码时是否自动跟随 Location 字段指定的新 URL。

      • 当设置为 true 时,客户端不会自动重定向,而是将 3xx 响应直接交给应用层处理。此时,开发者可以通过 HTTP_EVENT_REDIRECT 回调,自行决定是否跟随重定向、是否修改请求头或是否终止请求。

      • 当设置为 false``(默认值)时,客户端会自动按照 ``Location 进行重定向请求,适合大多数通用场景。

    • max_redirection_count 用于限制客户端自动跟随重定向的次数。

      • 在某些服务配置错误或恶意场景下,可能出现无限重定向循环,导致请求无法结束并消耗系统资源。通过该参数可设定最大允许次数(如 5 次),一旦超过该次数,客户端会终止请求并返回错误。

      • 该值为非负整数,当值为 0 时,将使用库的默认限制(不同版本 SDK 可能会调整),为了在未明确配置时仍能避免无限循环。。

Basic 认证

Basic 认证是 HTTP 协议中最简单的一种身份验证机制,用于在客户端与服务器之间确认用户身份。客户端在请求受保护资源时,将用户名和密码通过 Base64 编码附加在 HTTP 请求头的 Authorization 字段中发送给服务器。由于 Base64 编码仅用于传输格式,并不提供加密,因此未经 HTTPS 加密的传输容易被截获,安全性较低。

Basic 认证的主要优点是实现简单、兼容性好,适用于快速实现用户认证的场景,尤其在受控网络或 HTTPS 加密通信下使用更为安全。它适用于以下情况:

  1. 当需要快速实现 HTTP 层用户身份验证,且系统环境受控,风险较低时。

  2. 当需要与受信任的服务器或服务端接口交互时,如 REST API、局域网管理服务。

  3. 希望通过简单方式实现客户端自动认证,而无需复杂摘要计算或加密操作时。

执行流程

Basic 认证的常规全流程可以总结如下:

  1. 客户端请求受保护资源:

  • 客户端向服务器发送 HTTP 请求,且尚未提供认证信息。

  • 服务器检测到发送的请求需要认证,返回 401 Unauthorized 响应。

  1. 服务器返回认证挑战

  • 响应头包含 WWW-Authenticate 字段,指明认证类型为 Basic,并提供 realm ,用于标识认证域。

  1. 客户端生成认证响应

  • 客户端将用户名和密码按 username:password 的格式拼接,并进行 Base64 编码。

  • 将编码结果附在 Authorization 请求头中,并重新发起请求。

  1. 服务器验证响应

  • 服务器解析 Base64 编码,获取用户名和密码,并与本地存储或认证机制进行比对。

  • 如果匹配,则返回客户端请求的资源内容;否则继续返回 401 并重复上述流程。

  1. 后续请求

  • 对同一认证域的后续请求,客户端可继续使用相同的 Authorization 头,无需重复生成。

  • 可通过配置客户端参数(如 auth_typemax_authorization_retries)实现自动重试和认证处理。

Digest 认证

Digest 认证是一种 HTTP 协议层的身份验证机制,用于在客户端与服务器之间安全地验证用户身份。该认证通过对用户名、密码以及请求信息(如 URI、随机数 nonce 等)进行哈希计算(常用 MD5 或 SHA-256),生成一个摘要值(digest)发送给服务器,而不是直接传输明文密码。

通过 Digest 认证,客户端不在网络上直接发送明文密码,可以有效防止明文密码泄露,提升安全性。同时,由于服务器提供的随机数(nonce)在摘要计算中参与,可以防止攻击者重复使用请求包进行认证。此外,该认证在不使用 HTTPS 的情况下,相比 Basic 认证更安全,而在 HTTPS 下可进一步增强安全性。

该认证适用于以下场景:

  1. 当需要在 HTTP 协议层验证用户身份,但不希望直接传输明文密码时。

  2. 适合客户端与受控服务器之间的认证,例如 REST API 接口或局域网内的管理服务。

  3. 在要求比 Basic 认证更高的安全性,但又不方便部署完整 TLS 双向认证的情况下。

执行流程

Digest 认证的常规全流程可以总结如下:

  1. 客户端请求受保护资源:

  • 客户端向服务器发送 HTTP 请求,且尚未提供认证信息。

  • 服务器检测到发送的请求需要认证,返回 401 Unauthorized 响应。

  1. 服务器返回认证挑战

  • 响应头包含 WWW-Authenticate 字段,指定 Digest 认证参数:

    • realm:认证域,用于区分不同保护区域。

    • nonce:一次性随机数,用于防止重放攻击。

    • algorithm:摘要算法(如 MD5、SHA-256)。

    • qop (可选):质量保护选项,如 auth。

    • opaque (可选):服务器生成的随机值,用于防篡改。

  1. 客户端生成认证响应

  • 客户端使用用户名、密码以及服务器返回的 realmnonce 等参数生成摘要(response)。

  • 计算公式根据 algorithm 确定,例如 MD5 或 SHA-256。

  • 生成的响应附在 Authorization 请求头中,并重新发起请求。

  1. 服务器验证响应

  • 服务器根据相同算法计算预期摘要,并与客户端提供的 response 进行比对。

  • 如果匹配,则返回客户端请求的资源内容;否则继续返回 401 并重复上述流程。

  1. 后续请求

  • 对同一认证域的后续请求可重用最近的 nonce 或刷新 nonce,继续使用 Digest 认证。

摘要算法

在 HTTP Digest 认证中,算法决定客户端如何计算摘要以响应服务器的挑战,通常使用以下两种算法:

MD5 (Message Digest 5)是一种输出长度为 128 位(16 字节)的摘要算法,计算速度快、历史悠久,但已被证明存在碰撞漏洞,因此不适合安全敏感场景,适用于非安全性校验、文件完整性检测或历史兼容需求。

SHA-256 (Secure Hash Algorithm 256)输出长度为 256 位(32 字节),安全性更高、抗碰撞能力强,目前被认为安全,可用于加密签名、密码存储及 TLS/SSL 等安全通信中。

URL 编码

URL 编码(也称 percent-encoding)用于将 URL 中的特殊字符或非 ASCII 字符转换为合法的 ASCII 字符,保证 HTTP 请求能够正确传输和解析。

URL 中某些字符有特殊含义或不允许直接出现,例如:

  • ? 用于分隔路径和查询。

  • & 用于分隔多个查询参数。

  • # 表示 URL 锚点。

  • 空格、中文或其他非 ASCII 字符。

如果直接在 URL 中使用这些字符,可能导致请求格式错误、服务器解析失败以及数据丢失或错误。因此,当查询参数包含空格、特殊符号或非 ASCII 字符时,必须进行 URL 编码。

执行流程

URL 编码的通用流程可以总结如下:

  1. 确定需要编码的字符。

  2. 转换字符为 ASCII 值。

  3. 生成编码格式:

  • 使用 % 符号加上十六进制值表示该字符。

  • 例如空格表示为 %20# 表示为 %23,中文“中”表示为 %E4%B8%AD (UTF-8 编码后按字节转换)。

  1. 替换原字符串:

  • 将原字符串中需要编码的字符逐一替换为 %XX 形式,生成最终编码后的字符串。

  1. 拼接到 URL:

  • 将编码后的字符串作为查询参数附加在 URL 路径后,用 ? 分隔。

在实际开发中,可以调用 ESP-IDF 提供的示例函数 example_uri_encode() 来完成 URL 编码。该函数封装了通用流程中的核心步骤,包括判断哪些字符需要编码、将这些字符转换为 %XX 十六进制表示,并生成编码后的字符串。开发者只需将原始查询参数传入该函数,即可得到安全、可用于 HTTP GET 请求的编码字符串,然后将其附加到请求中,无需手动逐字符编码,从而简化开发流程并避免编码错误。

异步请求

异步请求指客户端发起 HTTPS 请求后,不会阻塞等待服务器响应,而是立即返回控制权,允许程序继续执行其他任务。其特点是可以在请求过程中同时处理其他操作,并通过事件回调或轮询方式处理响应数据。

设置为异步请求时,调用 esp_http_client_perform() 可能返回 ESP_ERR_HTTP_EAGAIN,表示请求尚未完成。所以在执行过程中需要循环调用该函数,直到返回非 ESP_ERR_HTTP_EAGAIN

异步请求的优势在于不会阻塞主任务,提高系统响应能力,尤其适合同时处理多个 HTTPS 请求或其他任务的场景。相比之下,同步请求在调用 esp_http_client_perform() 后会阻塞直到请求完成或超时,虽然实现简单,但在高并发或长延迟场景下容易阻塞其他任务,影响执行效率。