开始前适用开发板:ESP32-S3 Korvo · 开发框架:ESP-IDF
适用开发板:Korvo S3 · 工程
02.beginner.http_server· targetesp32s3
前置:Wi-Fi Station
学习时长:约 25 分钟 · 难度:★★☆☆☆
学习目标
完成本节后,你将能够:
- 理解 HTTP 协议的请求-响应模型
- 掌握 ESP-IDF
httpd组件的 URI handler 注册机制 - 学会处理 GET/POST 请求,提取 query 参数和请求体
- 能够设计简单的 RESTful API 控制设备
1. 这个例子在干嘛
把 ESP32-S3 变成一个 Web 服务器。连接 Wi-Fi 后,你的手机或电脑浏览器可以访问板子的 IP 地址,看到返回的页面或数据。
生活类比:就像你访问 http://192.168.1.1 进入路由器管理页面一样——现在你的 ESP32 也能提供类似的服务。
┌──────────┐ ┌──────────────┐
│ 浏览器 │ GET /hello │ ESP32-S3 │
│ (Client) │ ──────────────────→│ HTTP Server │
│ │ │ │
│ │ 200 "Hello World" │ URI Handler │
│ │ ←──────────────────│ 匹配路径 │
└──────────┘ └──────────────┘
2. 编译烧录
cd Korvo_Firmware\02.beginner.http_server
idf.py set-target esp32s3
idf.py menuconfig # 配置 Wi-Fi SSID/密码
idf.py build flash monitor
3. menuconfig 配置
| 选项 | 说明 |
|---|---|
ESP_WIFI_SSID | 路由器 Wi-Fi 名称 |
ESP_WIFI_PASSWORD | Wi-Fi 密码 |
连接成功后,屏幕显示 http://<IP> 和 running 状态。
4. 浏览器测试
假设屏幕显示 IP 为 192.168.1.50:
| 测试 | 浏览器地址栏 | 预期结果 | 串口输出 |
|---|---|---|---|
| 基本 GET | http://192.168.1.50/hello | 页面显示 "Hello World" | 请求日志 |
| 带参数 | http://192.168.1.50/hello?name=test | 同上 | 串口打印 query 内容 |
| POST | 用 Postman/curl 发 POST /echo | 返回 body 原文 | 打印收到的 body |
用 curl 测试 POST:
curl -X POST http://192.168.1.50/echo -d "hello from curl"
具体路由以工程源码注册为准。
5. HTTP 协议基础(3 分钟速通)
5.1 请求结构
GET /hello?name=world HTTP/1.1 ← 方法 + 路径 + 版本
Host: 192.168.1.50 ← 请求头
Content-Type: text/plain ← 请求头
← 空行
(POST 时这里有 body) ← 请求体
5.2 常用 HTTP 方法
| 方法 | 用途 | 示例 |
|---|---|---|
| GET | 获取数据 | 读取传感器值 |
| POST | 提交数据 | 发送控制命令 |
| PUT | 更新数据 | 修改设备配置 |
| DELETE | 删除数据 | 清除日志 |
5.3 响应结构
HTTP/1.1 200 OK ← 状态码
Content-Type: text/html ← 响应头
← 空行
Hello World ← 响应体
6. 关键文件与代码解析
| 文件 | 作用 | 重点关注 |
|---|---|---|
main/main.c | 全部 httpd 逻辑 | handler 注册与实现 |
6.1 核心 API
| API | 说明 |
|---|---|
httpd_start(&server, &config) | 启动 HTTP 服务器 |
httpd_register_uri_handler(server, &uri) | 注册路径处理函数 |
httpd_req_get_url_query_str(req, buf, len) | 获取 URL query 参数 |
httpd_req_recv(req, buf, len) | 读取 POST body |
httpd_resp_send(req, resp, len) | 发送响应 |
httpd_resp_send_chunk(req, chunk, len) | 分块发送(大数据) |
httpd_stop(server) | 停止服务器 |
6.2 URI Handler 结构
httpd_uri_t hello = {
.uri = "/hello", // 匹配的路径
.method = HTTP_GET, // 匹配的 HTTP 方法
.handler = hello_get_handler, // 回调函数
.user_ctx = NULL // 用户自定义数据(可传传感器指针等)
};
// 回调函数
esp_err_t hello_get_handler(httpd_req_t *req) {
// 1. (可选)读取 query 参数
// 2. 处理业务逻辑
// 3. 发送响应
httpd_resp_send(req, "Hello World", HTTPD_RESP_USE_STRLEN);
return ESP_OK;
}
URI handler 本质 = 路径 + HTTP 方法 + 回调函数。同一个路径可以注册不同方法的 handler(GET 读、POST 写)。
6.3 完整流程
app_main
├── Wi-Fi 连接 → 获取 IP
├── httpd_start()
├── 注册 handler:
│ ├── /hello GET → 返回 "Hello World"
│ ├── /echo POST → 回显 body
│ └── /ctrl PUT → 控制 GPIO(示例)
└── 屏幕显示 http://<IP>
7. 常见问题与排查
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 浏览器无法访问 | PC 和板子不在同一 Wi-Fi | 确认同一路由器、同一子网 |
| 浏览器无法访问 | IP 地址不对 | 看串口/屏幕实际 IP |
| 浏览器无法访问 | 防火墙拦截 | 关闭 PC 防火墙试试 |
| 404 Not Found | 路径不匹配 | 检查注册的 URI 与访问路径是否一致 |
| POST 无响应 | handler 中未调用 httpd_resp_send | 每个 handler 必须 发送响应 |
| 中文乱码 | Content-Type 未设置 charset | httpd_resp_set_type(req, "text/html; charset=utf-8") |
8. 动手改造建议
- LED 控制 API:
GET /api/led?state=on→ 点亮 LED,返回 JSON{"led": "on"} - 传感器读取:
GET /api/sensor→ 返回 ADC 值或温度 - 简单网页:在 handler 中返回 HTML 字符串,包含按钮和 JavaScript
- 文件下载:将 SPIFFS 中的文件通过 HTTP 提供下载
- HTTP 客户端对比:跑同仓库
02.beginner.http_request,学习 ESP32 作为 HTTP Client 访问网站
9. 知识延伸
- HTTP Server vs HTTP Client:Server 等待别人来请求(本例);Client 主动去请求别人(如访问天气 API)
- RESTful API 设计:路径表示资源(
/led),方法表示操作(GET 读 / PUT 改),响应用 JSON - 并发连接:ESP-IDF httpd 默认最多 4~7 个并发连接(可配置),每个连接一个 socket
- HTTPS:在 HTTP 基础上加 TLS 加密,ESP-IDF 支持但需要证书,入门阶段先用 HTTP
10. 下一步
| 方向 | 推荐例程 | 说明 |
|---|---|---|
| OTA 升级 | OTA | HTTP 下载固件 |
| 摄像头图传 | camera_webserver | HTTP 推视频流 |
| HTTP 客户端 | 02.beginner.http_request | 反过来——板子请求网站 |
| MQTT 通信 | MQTT | 物联网长连接协议 |
| 通用 HTTP 教程 | HTTP 教程 | 深入 API |
酷世DIY · Kevincoooool