HTTP 请求
http_request 组件允许你发起 HTTP/HTTPS 请求。为此,你需要将它添加到设备的配置中:
# Example configuration entryhttp_request:-
id(可选,ID):手动指定用于代码生成的 ID。
-
follow_redirects(可选,boolean):启用遵循 HTTP 重定向。默认值为
true。 -
redirect_limit(可选,integer):启用时可遵循的最大重定向次数。默认值为
3。 -
timeout(可选,Time):请求的超时时间。默认值为
4.5s。 -
useragent(可选,string):请求的 User-Agent 请求头。默认为
ESPHome/<version> (https://esphome.io),其中<version>是设备正在运行的 ESPHome 版本。 例如:ESPHome/2024.6.0 (https://esphome.io) -
verify_ssl(可选,boolean):设为
true(默认)时,连接时将验证 SSL/TLS 证书;如果无效,连接将被中止。为此,ESP-IDF 的默认 ESP x509 证书 包被包含在构建中。该证书包包含 Mozilla NSS 根证书库中的完整根证书列表。仅在 ESP32 上支持;在其他平台上必须显式设为 false。 -
watchdog_timeout(可选,Time):更改连接/数据传输期间的看门狗超时时间。 在慢速连接或高延迟连接上可能有用。**除非你遇到因看门狗超时导致的设备重启,否则请勿更改此值;**这样做可能会阻止设备因真实问题而重启。仅在 ESP32 和 RP2040 上可用。
针对 ESP32:
- buffer_size_rx(可选,integer):更改 HTTP 接收缓冲区大小。默认值为
512。 - buffer_size_tx(可选,integer):更改 HTTP 发送缓冲区大小。默认值为
512。 - ca_certificate_path(可选,file path):PEM 编码的 CA 证书文件路径。用于在使用自签名或自定义 CA 证书的服务器连接时保持
verify_ssl启用状态同时进行验证。 该证书在编译时嵌入固件中。指定后,默认证书包将不被包含,从而减小固件大小。
针对 ESP8266:
-
tls_buffer_size_rx(可选,integer):更改 TLS 接收缓冲区大小。应设为
16384以适应现代 HTTP 服务器的 TLS 记录大小。这将显著增加 RAM 使用量,可能需要移除其他组件以释放 RAM。你可以使用调试组件检查最大空闲堆块。如果服务器配置为支持 MFL TLS 扩展,则此值可以减小,但大多数流行服务器(Traefik、Caddy、Cloudflare)不支持,nginx 默认也禁用了此功能。默认值为512。 -
tls_buffer_size_tx(可选,integer):更改 TLS 发送缓冲区大小。默认值为
512。 -
esp8266_disable_ssl_support(可选,boolean):确定是否在固件二进制中包含 HTTPS/SSL 支持。从构建中排除 SSL 库将使二进制文件变小,这对于内存受限的设备(512 kB 或 1 MB)可能是必需的。如果你在设备的日志中看到
Error: ESP does not have enough space to store OTA file,可能需要启用此 选项。默认值为false。将该选项设为true时:- HTTPS 连接将无法使用
- 隐含
verify_ssl: false
WARNING
将 verify_ssl 设为 false 会降低使用 HTTPS 连接时的安全性!
没有根证书包,远程 HTTPS 服务器使用的证书将无法被验证,从而使 HTTPS 连接面临中间人攻击的风险。
为了最大化安全性,请勿将 verify_ssl 设为 false,除非:
- 在非 ESP32 设备上使用 Arduino 框架,或
- 设备没有足够的内存来存储证书包
如果你需要在 ESP32 上连接到使用自签名或自定义 CA 证书的服务器,请改用
ca_certificate_path 选项,而不是禁用 verify_ssl。
我们强烈建议使用能够正确支持 TLS/SSL 的硬件。
针对主机平台:
- ca_certificate_path(可选,file path):CA 证书包路径。在 MacOS 上不需要(使用内置的 CA 包,默认启用 SSL)。 在 Linux 上,此选项是启用 SSL 所必需的。
NOTE
要在 Linux 上使用 SSL,你必须安装 libssl-dev 包(例如 sudo apt install libssl-dev )。
在 Linux 上,ca_certificate_path 的典型值为 /etc/ssl/certs/ca-certificates.crt。
http_request 组件支持多种操作,可用于发送请求。
http_request.get 操作
Section titled “http_request.get 操作”该操作发送 GET 请求。
on_...: - http_request.get: url: https://esphome.io request_headers: Content-Type: application/json on_response: then: - logger.log: format: 'Response status: %d, Duration: %u ms' args: - response->status_code - response->duration_ms # Short form - http_request.get: https://esphome.io-
url(必选,string,templatable):发送请求的 URL。
-
request_headers(可选,mapping):HTTP 请求头的映射。值是可模板化的。
-
collect_headers(可选,list of strings):要从响应中收集的 HTTP 请求头名称列表。
-
capture_response(可选,boolean):设为
true时,将捕获响应数据并将其作为std::string放入body变量,供在lambdas中使用。默认值为false。 -
max_response_buffer_size(可选,integer):用于存储响应的最大缓冲区大小。 默认值为
1 kB。 -
on_response(可选,Automation):收到请求后执行的自动化。
-
on_error(可选,Automation):请求无法完成时执行的自动化。
http_request.post 操作
Section titled “http_request.post 操作”该操作发送 POST 请求。
on_...: - http_request.post: url: https://esphome.io request_headers: Content-Type: application/json json: key: value # Short form - http_request.post: https://esphome.io-
body(可选,string,templatable):随请求一起发送的 HTTP 正文字符串。
-
来自
http_request.get操作的所有其他选项。
http_request.send 操作
Section titled “http_request.send 操作”该操作发送请求。
on_...: - http_request.send: method: PUT url: https://esphome.io request_headers: Content-Type: application/json body: "Some data"- method(必选,string):要使用的 HTTP 方法(
GET、POST、PUT、DELETE、PATCH)。 - 来自
http_request.post操作和http_request.get操作的所有其他选项。
on_response 触发器
Section titled “on_response 触发器”该自动化将在 HTTP 请求完成时触发。 以下变量可用于在lambdas中使用:
response作为指向HttpContainer对象的指针,其中包含content_length、status_code和 ` duration_ms“。std::string get_response_header(const std::string &header_name)用于读取响应头(仅可用collect_headers中指定名称的头)。body作为std::string,当capture_response(参见http_request.get操作)设为true时包含响应正文。
NOTE
使用 body 变量之前应检查 status_code。成功响应通常的状态码为
200。服务器错误(如“未找到”(404)或“内部服务器错误”(500))将具有相应的状态码,并可能在 body 变量中包含错误消息。
on_... then: - http_request.get: url: https://esphome.io collect_headers: - Content-Type on_response: then: - logger.log: format: "Response status: %d, Duration: %u ms, Content-Type: %s" args: - response->status_code - response->duration_ms - response->get_response_header("Content-Type").c_str() - lambda: |- ESP_LOGD(TAG, "Response status: %d, Duration: %u ms, Content-Type: %s", response->status_code, response->duration_ms, response->get_response_header("Content-Type").c_str()); on_error: then: - logger.log: "Request failed!"on_error 触发器
Section titled “on_error 触发器”该自动化将在 HTTP 请求无法完成时触发。这可能是由于网络不可用, 或服务器不可达等情况。如果请求 完成,即使响应码不是 200,也不会触发此触发器。无法获取错误类型的信息,也没有 可在lambdas中使用的变量。参见上面的示例用法。
可模板化的值
Section titled “可模板化的值”on_...: - http_request.post: url: !lambda |- return ((std::string) "https://esphome.io?state=" + id(my_sensor).state).c_str(); request_headers: X-Custom-Header: !lambda |- return ((std::string) "Value-" + id(my_sensor).state).c_str(); body: !lambda |- return id(my_sensor).state;JSON 格式的 POST 正文(语法 1)
Section titled “JSON 格式的 POST 正文(语法 1)”注意: 映射的所有值必须是字符串。使用此
语法无法发送 JSON boolean 或 numbers。
on_...: - http_request.post: url: https://esphome.io json: key: !lambda |- return id(my_sensor).state; greeting: "Hello World"
# Will send: # {"key": "42.0", "greeting": "Hello World"}JSON 格式的 POST 正文(语法 2)
Section titled “JSON 格式的 POST 正文(语法 2)”注意: 使用此语法发送 JSON 中的 boolean 或 numbers。
JSON 消息将使用 ArduinoJson 库构建。
在 json 选项中你可以访问一个 root 对象,它代表 JSON 消息的基础对象。你可
以使用 root["KEY_NAME"] = VALUE; 语法将值赋给键,如下所示。
on_...: - http_request.post: url: https://esphome.io json: |- root["key"] = id(my_sensor).state; root["greeting"] = "Hello World";
# Will send: # {"key": 42.0, "greeting": "Hello World"}从 JSON 正文响应中获取值
Section titled “从 JSON 正文响应中获取值”如果你想获取 vol 键的值并将其赋给 id 设置为 player_volume 的模板传感器或 number 组件,可以这样做,但请注意,检查键的存在将避免难以阅读 的错误消息:
本示例假设服务器返回类似于以下内容的 JSON 对象作为响应:
{"status":"play","vol":"42","mute":"0"}
如果你想获取 vol 键的值并将其赋给 id 设置为 player_volume 的模板 sensor 或 number 组件:
on_...:- http_request.get: url: https://esphome.io capture_response: true on_response: then: - if: condition: lambda: return response->status_code == 200; then: - lambda: |- json::parse_json(body, [](JsonObject root) -> bool { if (root["vol"]) { id(player_volume).publish_state(root["vol"]); return true; } else { ESP_LOGI(TAG,"No 'vol' key in this json!"); return false; } }); else: - logger.log: format: "Error: Response status: %d, message %s" args: [ 'response->status_code', 'body.c_str()' ]