网页服务器
ESP32 内置了 Wi-Fi 功能,能够作为网页服务器(Web Server)向网络中的其他设备提供服务。通过在 ESP32 上运行网页服务器,可以创建基于浏览器的用户界面,用于监控传感器数据或控制设备状态,是实现物联网(IoT)应用的基础功能之一。
1. WebServer
库简介
Arduino-ESP32 核心库内置了 WebServer.h
,它提供了一套简洁的 API 来快速构建 Web Server。通过注册路由(URL 路径)及回调函数,实现请求分发与应答。适用于绝大多数典型 IOT 项目的本地网页交互。本教程将使用此库。
- 简洁易用,适合入门和资源受限场景。
- 需在主循环 (
loop()
) 中定期调用server.handleClient()
以处理客户端请求。 - 对大流量/高并发等复杂场景建议选用异步库(如 ESPAsyncWebServer)。
2. 示例 1:基础网页服务(STA 模式)
在 STA 模式下创建一个基础的网页服务器,用于显示一个包含"Hello World!"的静态页面。
2.1 代码
#include <WiFi.h>
#include <WebServer.h>
const char *ssid = "Maker";
const char *password = "12345678";
WebServer server(80);
void setup() {
Serial.begin(115200);
delay(10);
// 连接 WiFi 网络
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
// 等待连接成功
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
// 配置路由和启动服务器
server.on("/", handleRoot);
server.begin();
}
void loop() {
server.handleClient();
}
// 处理根路径请求
void handleRoot() {
server.send(200, "text/html", generateHTML());
}
// 生成 HTML 页面内容
String generateHTML() {
String htmlContent = "<!DOCTYPE html> <html>\n";
htmlContent += "<head><meta name=\"viewport\" content=\"width=device-width\">\n";
htmlContent += "<title>ESP32S3 Test</title>\n";
htmlContent += "</head><body>\n";
htmlContent += "<h1>Hello World!</h1>\n";
htmlContent += "</body>\n";
htmlContent += "</html>\n";
return htmlContent;
}
2. 代码解释
#include <WebServer.h>
:引入 Web Server 库,用以在 ESP32 上创建 HTTP 服务器。WebServer server(80);
:创建一个服务器对象,监听标准的 HTTP 端口80
。80 是 HTTP 协议的默认端口。server.on("/", handleRoot);
:注册路由处理函数。当客户端访问根路径"/"时,调用handleRoot()
函数。server.begin();
:启动服务器,开始监听客户端的连接请求。server.handleClient();
:在loop()
中持续调用,处理传入的客户端请求。handleRoot()
:这是一个自定义的回调函数,用于处理特定路径的请求。server.send(statusCode, contentType, content);
:向客户端发送一个 HTTP 响应。向客户端浏览器返回包含 "Hello World" 的简单 HTML 页面。200
:HTTP 状态码,200 OK
表示请求成功。"text/html"
:MIME 类型,告知浏览器响应内容是 HTML 文本。generateHTML()
:函数返回的字符串,即网页的实际内容。
generateHTML()
:一个辅助函数,将 HTML 代码拼接成一个String
对象,返回包含完整 HTML 结构的字符串。
3. 运行结果
将代码中的 ssid
和 password
修改为目标 Wi-Fi 网络的名称和密码后上传。串口监视器将显示连接过程和获取到的 IP 地址。在同一局域网的设备上打开浏览器,输入显示的 IP 地址,即可看到"Hello World!"页面。
3. 示例 2:通过网页控制 LED (STA 模式)
在 STA 模式下,开启网页服务器。同局域网下的设备,通过网页控制 ESP32 连接的 LED 状态。
3.1 搭建电路
需要使用的器件有:
- LED * 1
- 330Ω 电阻 * 1
- 面包板 * 1
- 导线
- ESP32 开发板
按照下面接线图连接电路:
ESP32-S3-Zero 引脚图

3.2 代码
#include <WiFi.h>
#include <WebServer.h>
const int ledPin = 7;
const char *ssid = "Maker";
const char *password = "12345678";
WebServer server(80);
String generateHTML(bool ledState = false);
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(115200);
// 连接 WiFi 网络
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
// 等待连接成功
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
// 配置路由和启动服务器
server.on("/", handleRoot);
server.on("/ledon", handleLedOn);
server.on("/ledoff", handleLedOff);
server.begin();
}
void loop() {
server.handleClient();
}
// 处理根路径请求
void handleRoot() {
server.send(200, "text/html", generateHTML(digitalRead(ledPin)));
}
// 开启 LED
void handleLedOn() {
digitalWrite(ledPin, HIGH);
server.send(200, "text/html", generateHTML(true));
}
// 关闭 LED
void handleLedOff() {
digitalWrite(ledPin, LOW);
server.send(200, "text/html", generateHTML(false));
}
// 生成 HTML 页面内容
String generateHTML(bool ledState) {
String htmlContent = "<!DOCTYPE html> <html>\n";
htmlContent += "<head><meta name=\"viewport\" content=\"width=device-width\">\n";
htmlContent += "<title>ESP32S3 Test</title>\n";
htmlContent += "</head><body>\n";
htmlContent += "<h1>Hello World!</h1>\n";
if (ledState) {
htmlContent += "<p>LED Status: ON</p>";
htmlContent += "<a href=\"/ledoff\">LED OFF</a>\n";
} else {
htmlContent += "<p>LED Status: OFF</p>";
htmlContent += "<a href=\"/ledon\">LED ON</a>\n";
}
htmlContent += "</body>\n";
htmlContent += "</html>\n";
return htmlContent;
}
3.3 代码解析
-
新增路由:
-
server.on("/ledon", handleLedOn);
:将
/ledon
路径的请求绑定到handleLedOn
函数。当浏览器访问http://<IP 地址>/ledon
时,服务器将调用handleLedOn
函数。 -
server.on("/ledoff", handleLedOff);
:同理,将
/ledoff
路径绑定到handleLedOff
函数。当浏览器访问http://<IP 地址>/ledoff
时,服务器将调用handleLedOff
函数。
-
-
LED 控制:
-
使用 HTML 的
<a>
标签创建链接按钮,点击时会向相应的路径发送 GET 请求,实现 LED 的控制。当用户点击“LED ON”链接时,浏览器会向服务器的
/ledon
路径发起一个 HTTP GET 请求。服务器收到后,
server.handleClient()
会匹配到server.on("/ledon", handleLedOn);
,进而执行handleLedOn
函数。 -
在
handleLedOn
和handleLedOff
函数中,首先通过digitalWrite()
控制 LED 状态。执行硬件操作后,它们会再次调用generateHTML()
生成新的页面并发送给客户端,以更新页面状态。
-
-
动态 HTML:
generateHTML(bool ledState)
函数现在接受一个布尔参数,代表 LED 的当前状态。- 函数内部使用
if-else
语句,根据ledState
的值,动态地生成不同的 HTML 内容。如果灯是亮的,就显示 "OFF" 按钮;如果灯是灭的,就显示 "ON" 按钮。
3.4 运行结果
上传代码后,打开串口监视器查看 IP 地址。然后在浏览器中访问该 IP 地址,页面会显示当前 LED 状态和控制按钮。点击"LED ON"或"LED OFF"按钮可以控制 LED 的开关状态,页面会实时更新显示当前状态。
以上网页未做页面美化,仅用作功能演示,可自行扩展 HTML/CSS 实现更友好的用户界面。
4. 示例 3:通过网页控制 LED (AP 模式)
在 AP 模式下,开启网页服务器。其他设备连接 ESP32 创建的 Wi-Fi 热点后,可直接通过网页访问 ESP32 提供的服务器,实现对 LED 状态的控制。
4.1 搭建电路
需要使用的器件有:
- LED * 1
- 330Ω 电阻 * 1
- 面包板 * 1
- 导线
- ESP32 开发板
按照下面接线图连接电路:
ESP32-S3-Zero 引脚图

4.2 代码
#include <WiFi.h>
#include <WebServer.h>
const int ledPin = 7;
const char *ssid = "ESP32S3-TEST"; // 设置热点名称
const char *password = "12345678"; // 设置热点密码(至少 8 位)
WebServer server(80);
String generateHTML(bool ledState = false);
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(115200);
// 创建 Wi-Fi 热点
Serial.println("Configuring access point...");
if (!WiFi.softAP(ssid, password)) {
Serial.println("Soft AP creation failed.");
while (1)
;
}
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
// 配置路由和启动服务器
server.on("/", handleRoot);
server.on("/ledon", handleLedOn);
server.on("/ledoff", handleLedOff);
server.begin();
}
void loop() {
server.handleClient();
}
// 处理根路径请求
void handleRoot() {
server.send(200, "text/html", generateHTML(digitalRead(ledPin)));
}
// 开启 LED
void handleLedOn() {
digitalWrite(ledPin, HIGH);
server.send(200, "text/html", generateHTML(true));
}
// 关闭 LED
void handleLedOff() {
digitalWrite(ledPin, LOW);
server.send(200, "text/html", generateHTML(false));
}
// 生成 HTML 页面内容
String generateHTML(bool ledState) {
String htmlContent = "<!DOCTYPE html> <html>\n";
htmlContent += "<head><meta name=\"viewport\" content=\"width=device-width\">\n";
htmlContent += "<title>ESP32S3 Test</title>\n";
htmlContent += "</head><body>\n";
htmlContent += "<h1>Hello World!</h1>\n";
if (ledState) {
htmlContent += "<p>LED Status: ON</p>";
htmlContent += "<a href=\"/ledoff\">LED OFF</a>\n";
} else {
htmlContent += "<p>LED Status: OFF</p>";
htmlContent += "<a href=\"/ledon\">LED ON</a>\n";
}
htmlContent += "</body>\n";
htmlContent += "</html>\n";
return htmlContent;
}
4.3 代码解析
- AP 模式配置:使用
WiFi.softAP(ssid, password)
创建 Wi-Fi 热点,而不是连接到现有网络。 WiFi.softAPIP()
:获取 ESP32 作为热点时的 IP 地址,通常默认为 192.168.4.1。- 独立网络:ESP32 创建自己的局域网,其他设备需要先连接到这个热点才能访问网页服务器。
- 网页服务器逻辑:处理 HTTP 请求的逻辑与 STA 模式下的示例基本一致,主要区别在于网络连接的初始化方式。
4.4 运行结果
上传代码后,ESP32 会创建一个名为"ESP32S3-TEST"的 Wi-Fi 热点。使用电脑或手机连接此热点(密码:12345678),然后在浏览器中访问 192.168.4.1,即可看到 LED 控制页面。点击按钮可以控制 LED 的开关状态。