Arduino for ESP8266&ESP32适用库ESPAsyncWebServer:静态文件和模板引擎

目的

对于WebServer来说静态文件也是非常重要的一块。通常一个网页有很多文件组成,比如一个主页通常由index.html、favicon.ico等多个文件组成,用户访问 /index.html 时,浏览器接收到 index.html 文件后还会再请求该文件中关联的其它文件,这些文件名称和类型等都是无法预料的,一条条添加对应的url就非常不方便了,这个时候就需要用到静态文件服务了。
静态文件中通常可以使用模板引擎方便的实现界面与数据的分离,减少开发过程中的工作量,特定情景下还是蛮好用的。
这篇文章将对上面两块相关内容进行介绍。

本文中各例程演示均在ESP32中进行。

静态文件服务

功能说明

使用静态文件服务首先需要启动相关的文件系统,除了可以使用Flash上的SPIFFS系统,还可以使用SD卡等。初始完成后就可以用 AsyncWebServer 对象的 serveStatic() 方法来设置静态文件服务了,比如下面这样:

// 用户访问/page.htm时,返回SPIFFS中/www/page.htm文件
server.serveStatic("/page.htm", SPIFFS, "/www/page.htm");

上面的方式指定了文件到文件,事实上大多数情况是不会这么用的,而是下面这样:

// 用户访问/目录下文件时返回SPIFFS中/www/路径下同名文件
// 比如用户访问/page.htm时,将会返回SPIFFS中/www/page.htm文件
// 比如用户访问/favicon.ico时,将会返回SPIFFS中/www/favicon.ico文件
// ……
// 特殊情况:用户访问/时,默认将会返回SPIFFS中/www/index.htm文件(如果存在)
server.serveStatic("/", SPIFFS, "/www/");

上面上面的使用方式是最常用的方式,上面的方式中有一种特殊情况,就是用户访问根目录时返回了index.htm文件,这个默认返回的文件也可以手动定义,使用下面方法:

// 用户访问/时,默认返回将变成SPIFFS中/www/default.html文件
server.serveStatic("/", SPIFFS, "/www/").setDefaultFile("default.html");

客户端如果多次打开网页,每次都从服务器获取静态文件的话对性能影响还是蛮大的,这时候就可以使用Cache-Control和Last-Modified来优化性能。
Cache-Control可以设定一个时间,客户端在获取到某个文件后将文件进行缓存,这段时间内如果再需要这个文件的话将不再从服务器获取,而是直接使用缓存。下面是Cache-Control的使用示例:

// 设定缓存事件600秒,客户端获取过的文件将在客户端缓存600秒
// 600秒内需要已缓存的文件将直接使用缓存,不再从服务器获取
server.serveStatic("/", SPIFFS, "/www/").setCacheControl("max-age=600");

// 使用下面方式就可以随时更改Cache-Control
AsyncStaticWebHandler* handler = &server.serveStatic("/", SPIFFS, "/www/").setCacheControl("max-age=600");
handler->setCacheControl("max-age=30");

Cache-Control除了上面功能外还有很多别的功能,不同功能下setCacheControl中填入的参数不同,比如填入 "no-store" 参数的话将禁用所有缓存。Cache-Control参数更多内容可以参考 Cache-Control

Last-Modified将设置一个时间参数,客户端如果缓存过文件,下次再需要该文件向服务器请求时将附带缓存文件的时间参数,服务器比较两个参数,如果服务器中的参数较新的话将发送新的文件,否则客户端将使用缓存文件。下面是Last-Modified的使用示例:

// 设定文件最后修改时间参数
AsyncStaticWebHandler* handler = &server.serveStatic("/", SPIFFS, "/www/").setLastModified("Mon, 26 Apr 2010 13:22:17 GMT");
Mon, 26 Apr 2010 13:22:17 GMT

// 更新文件最后修改时间参数
handler->setLastModified("Mon, 20 Jun 2016 14:00:00 GMT");

静态文件服务可以设置身份认证,用户必须通过认证后才能访问其中的文件:

// setAuthentication()中分别填入用户名和密码
server.serveStatic("/", SPIFFS, "/www/").setAuthentication("user", "pass");

除了上面的功能外静态文件服务还可以应用过滤器和模板引擎。下面是应用过滤器的示例(模板引擎的示例将在模板引擎章节介绍):

server.serveStatic("/", SPIFFS, "/www/").setFilter(ON_STA_FILTER); // ESP32处于STA模式时起效
server.serveStatic("/", SPIFFS, "/ap/").setFilter(ON_AP_FILTER); // ESP32处于AP模式时起效

从上面的介绍可以看到静态文件服务可选的参数非常多,如果需要设置多个参数的话可以使用下面两种方式:

// 方式一
server.serveStatic("/", SPIFFS, "/www/").setDefaultFile("default.html").setCacheControl("max-age=600");

// 方式二
AsyncStaticWebHandler* handler = &server.serveStatic("/", SPIFFS, "/www/");
handler->setDefaultFile("default.html");
handler->setCacheControl("max-age=600");

使用演示

这里以使用SPIFFS作为文件系统进行静态文件服务功能演示,首先准备几个文件。将下面文本保存为名为index.html的文件:

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <title>ServeStatic Test</title>
    <link rel="stylesheet" type="text/css" href="mystyle.css">
</head>
<body>
    <p>这是静态文件服务测试</p>
    <p>本页面的背景颜色是由mystyle.css文件提供的</p>
    <p>本页面引用了mystyle.css文件,浏览器在解析时会自动向服务器请求该文件</p>
</body>
</html>

将下面文本保存为名为mystyle.css的文件:

body {
    background-color: gray;
}

在Arduino中使用下面代码:

#include <WiFi.h>
#include <SPIFFS.h>
#include <ESPAsyncWebServer.h> //引入相应库

const char *ssid = "********";
const char *password = "********";

AsyncWebServer server(80); //声明WebServer对象

void setup()
{
  Serial.begin(115200);
  Serial.println();

  WiFi.mode(WIFI_STA);
  WiFi.setSleep(false);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("Connected");
  Serial.print("IP Address:");
  Serial.println(WiFi.localIP());

  SPIFFS.begin(true); //挂载SPIFFS,如果挂载失败则格式化生成SPIFFS,格式化时间较长
  //当然上面begin中不填true格式化也行,下面演示中用工具上传文件时会自动生成SPIFFS

  server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.html");

  server.begin(); //启动服务器

  Serial.println("Web server started");
}

void loop(){}

在这里插入图片描述
上面使用了名为 ESP32 Sketch Data Upload 的工具来将 项目文件夹下data文件夹中 的网页相关文件上传到ESP32的SPIFFS中。一切就绪后在浏览器中访问就可以看到网页被正确的加载出来了,单独访问两个文件也没问题。

上传文件用到的工具项目地址如下:
https://github.com/me-no-dev/arduino-esp32fs-plugin
从项目地址下载Release版本压缩包,将其解压到Arduino安装文件夹tools文件夹下,最终文件路径为: .../Arduino/tools/ESP32FS/tool/esp32fs.jar 。重启Arduino IDE后就可以在菜单中看到选项。

ESP8266上传文件到SPIFFS的工具项目地址如下:
https://github.com/esp8266/arduino-esp8266fs-plugin

SPIFFSEditor

ESPAsyncWebServer库中有一个SPIFFSEditor功能,可以通过网页管理和编辑文件系统中的文件,这里做个简单的使用演示:

#include <WiFi.h>
#include <SPIFFS.h>
#include <ESPAsyncWebServer.h> //引入相应库
#include <SPIFFSEditor.h> //引入相应库

const char *ssid = "********";
const char *password = "********";

AsyncWebServer server(80); //声明WebServer对象

const char* http_username = "admin";
const char* http_password = "123456";

void setup()
{
  Serial.begin(115200);
  Serial.println();

  WiFi.mode(WIFI_STA);
  WiFi.setSleep(false);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("Connected");
  Serial.print("IP Address:");
  Serial.println(WiFi.localIP());

  SPIFFS.begin(true);

  server.addHandler(new SPIFFSEditor(SPIFFS, http_username,http_password));

  server.begin(); //启动服务器

  Serial.println("Web server started");
}

void loop(){}

在这里插入图片描述
上面就是SPIFFSEditor的演示了,需要注意的是SPIFFSEditor的网页中用到了外部的文件,需要能连上互联网才能正确加载。

模板引擎

ESPAsyncWebServer中的模板引擎目前只支持一个功能,实际值替换占位符。该模板引擎使用 % 来标识占位符,先看下面演示:

#include <WiFi.h>
#include <ESPAsyncWebServer.h> //引入相应库

const char *ssid = "********";
const char *password = "********";

AsyncWebServer server(80); //声明WebServer对象

int count = 0;

String processor(const String& var)
{
  if(var == "VAR1")
  {
    count++;
    return String(count);
  }
  else if(var == "VAR2")
  {
    return "lalala~~~";
  }
  else if(var == "VAR3")
  {
    return F("ABCDEFG"); // F() 是Arduino的PROGMEM机制,里面的字符串将存放在Flash中,减少对内存的占用
  }
  return String();
}

void handleRoot(AsyncWebServerRequest *request) //回调函数
{
   // 向客户端发送响应和内容
   // 注意文本中用 % % 包围的字符串,
  request->send_P(200, "text/plain", "count = %VAR1%, VAR2 = %VAR2%, VAR3 = %VAR3%", processor);
}

void setup()
{
  Serial.begin(115200);
  Serial.println();

  WiFi.mode(WIFI_STA);
  WiFi.setSleep(false);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("Connected");
  Serial.print("IP Address:");
  Serial.println(WiFi.localIP());

  server.on("/", HTTP_GET, handleRoot); //注册链接"/"与对应回调函数

  server.begin(); //启动服务器

  Serial.println("Web server started");
}

void loop(){}

在这里插入图片描述
ESPAsyncWebServer的模板引擎因为功能单一,从上面的演示中就可以完全理解了,模板引擎经常用在静态的文件中。除了上面演示用的方式还可以用下面的方式来使用:

const char index_html[] PROGMEM = "..."; // large char array, tested with 14k
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", index_html);
request->send(response);

或者直接在静态文件服务上使用也可以:

String processor(const String& var)
{
  if(var == "HELLO_FROM_TEMPLATE")
    return F("Hello world!");
  return String();
}

// ...

server.serveStatic("/", SPIFFS, "/www/").setTemplateProcessor(processor);

总结

ESPAsyncWebServer静态文件和模板引擎主要就是上面这些内容,更多内容可以查看项目官方的文档和例程,或者我的其他ESPAsyncWebServer的文章:
ESPAsyncWebServer项目地址:https://github.com/me-no-dev/ESPAsyncWebServer
《Arduino for ESP8266&ESP32适用库ESPAsyncWebServer:快速入门》
《Arduino for ESP8266&ESP32适用库ESPAsyncWebServer:事件处理绑定》
《Arduino for ESP8266&ESP32适用库ESPAsyncWebServer:请求与响应》
《Arduino for ESP8266&ESP32适用库ESPAsyncWebServer:静态文件和模板引擎》
《Arduino for ESP8266&ESP32适用库ESPAsyncWebServer:WebSocket和EventSource》

ESP8266模块可以通过Arduino IDE进行编程,并且可以通过编程来设置静态IP。以下是设置静态IP的基本步骤: 1. 首先,你需要确保已经安装了Arduino IDE,并且已经安装了ESP8266的开发板管理器和相关的文件。 2. 连接ESP8266模块到电脑上,并在Arduino IDE中选择正确的开发板和端口。 3. 在代码中,包含ESP8266WiFi,并且在`setup()`函数中配置WiFi连接,指定静态IP地址、网关、子网掩码和DNS服务器。 以下是一个简单的示例代码,展示如何为ESP8266设置静态IP: ```cpp #include <ESP8266WiFi.h> const char* ssid = "你的SSID"; const char* password = "你的密码"; // 设置静态IP地址、网关、子网掩码和DNS服务器 IPAddress staticIP(192, 168, 1, 100); IPAddress gateway(192, 168, 1, 1); IPAddress subnet(255, 255, 255, 0); IPAddress dns1(8, 8, 8, 8); // 使用Google的公共DNS void setup() { Serial.begin(115200); // 连接到WiFi网络 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()); // 设置静态IP WiFi.config(staticIP, gateway, subnet, dns1); } void loop() { // 你的代码逻辑 } ``` 在上述代码中,我们首先包含了`ESP8266WiFi`,并定义了网络的SSID和密码。然后我们设置了静态IP地址、网关、子网掩码和DNS服务器。在`setup()`函数中,我们尝试连接到WiFi网络,并在连接成功后,通过`WiFi.config()`函数来配置静态IP。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Naisu Xu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值