ESP32-Web-Server 实战编程-使用文件系统建立强大的 web 系统

ESP32-Web-Server 实战编程-使用文件系统建立强大的 web 系统

概述

在前述章节我们讲述了在网页端控制多个 GPIO 的案例。当程序开始变得复杂,让一些功能“自动起来”是一个好的选择。

在前面的示例中,我们需要在后端为每个前端代码的 URL 指定一个对应的 handler,在 URL 变的越来越多的情况下,这种处理将变的不那么方便。

此外,随着系统功能越来越多,前端设计中使用的 HTML文件、CSS 文件、JS 文件越来越多,如果系统能自动管理、加载对应的文件,将对项目的设计与维护是很大的改善。

本节开始,我们将在后端代码中使用文件系统,默认使用 ESP-IDF 提供的 SPIFFS 文件系统,读者也可以使用更为通用的 Fatfs 文件系统,本质上两者是等价的。

需求及功能解析

功能还是上节讲述的在网页控制一个 LED 灯的亮灭。

本节演示如何通过文件系统来保存前端(HTML、CSS、JS 文件)所需要的内容,并在后端系统中需要指定的文件时实现自动索引到 SPIFFS 文件系统中对应的前端文件。

在这里插入图片描述

示例解析

目录结构

├── CMakeLists.txt
├── main
│   ├── CMakeLists.txt
│   └── main.c                 User application
├── components
│   └── fs_image└── web_image└── index.html└── CSS└── JS└── CMakeLists.txt
└── README.md                  This is the file you are currently reading
  • 目录结构主要包含主目录 main,以及组件目录 components.

  • 其中组件目录components中包含了用于存储网页文件的 fs_image 目录(即前述前端文件),fs_image 目录下的 web_image 是文件系统中的内容。IDF 中通过 CMakeLists.txt 中指定的语句,将 web_image 中的内容,按照相同的目录结构写入到 ESP32 的 flash 存储器中:

    set(WEB_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/web_image")
    if (EXISTS ${WEB_SRC_DIR})spiffs_create_partition_image(fs ${WEB_SRC_DIR} FLASH_IN_PROJECT)
    else()message(FATAL_ERROR "${WEB_SRC_DIR} doesn't exit.")
    endif()
    

    在这里插入图片描述

前端代码

前端代码与上节的内容一致,只是存储目录更加规范,HTML、CSS、JS 分别是不同的文件:
在这里插入图片描述

此外,在 HTML 中对于需要的 CSS 文件、JS 文件,分别使用 hrefsrc 指定对应文件在文件系统中的存储位置:

<link rel="stylesheet" type="text/css" href="css/stylesheet.css">
<script src="js/script.js"></script>

后端代码

后端代码中主要是增加了文件系统的初始化,以及自动在文件系统中查找需要的文件的 handler。

1)增加文件系统的初始化:

/* Start the server for the first time */
ESP_ERROR_CHECK(init_fs());

2)在文件系统中增加查找文件的 handler:

httpd_uri_t httpd_uri_array[] = {{"/states", HTTP_GET, output_states_get_handler, rest_context},{"/update", HTTP_GET, update_state_get_handler, rest_context},{"/*", HTTP_GET, rest_common_get_handler,rest_context}//Catch-all callback function for the filesystem, this must be set to the array last one};

其中 “/states”、“/update” 分别是查询当前 GPIO 状态、更新 GPIO 状态的 ULR。

新增的 “/*” 是一个通配符,必须放在httpd_uri_array[] 的最后一个,代表上述所有未匹配到的 URL,都去这个通配符对应的 handler 里去查找对应的文件,获取对应的数据。这就是在文件系统中自动查找对应文件的关键处理函数。

当使用浏览器访问对应的 URL 时,会请求对应的文件,ESP32 将在 rest_common_get_handler() 中根据 URL 中指定的文件信息查找存储在 ESP32 SPIFFS 文件系统中的内容。

示例效果

在这里插入图片描述

讨论

1)前端代码与后端代码是有对应关系的,本示例中前端发出的 URL 中通过 ? 识别请求的文件名称,因此后端代码中有:

char* p = strrchr(filepath, '?');if (p != NULL) {*p = '\0';}int fd = open(filepath, O_RDONLY, 0);

2)不同的文件有不同的发送类型符号,本例中通过文件的后缀名,自动识别要打开的文件,并设置对应的文件类型描述符号:

/* Set HTTP response content type according to file extension */
static esp_err_t set_content_type_from_file(httpd_req_t* req, const char* filepath)
{const char* type = "text/plain";if (CHECK_FILE_EXTENSION(filepath, ".html")) {type = "text/html";} else if (CHECK_FILE_EXTENSION(filepath, ".js")) {type = "application/javascript";} else if (CHECK_FILE_EXTENSION(filepath, ".css")) {type = "text/css";} else if (CHECK_FILE_EXTENSION(filepath, ".png")) {type = "image/png";} else if (CHECK_FILE_EXTENSION(filepath, ".ico")) {type = "image/x-icon";} else if (CHECK_FILE_EXTENSION(filepath, ".svg")) {type = "text/xml";}return httpd_resp_set_type(req, type);
}

3)注意初始化 web 时,其文件系统的地址,要和实际使用的 spiffs mount 的 路径 web_base_point 要一致,否则会无法正确找到对应的文件:

server = start_webserver(web_base_point);
esp_err_t init_fs(void)
{esp_vfs_spiffs_conf_t conf = {.base_path = web_base_point,.partition_label = NULL,.max_files = 5,//maybe the num can be set smaller.format_if_mount_failed = false};...
}

总结

1)本节主要是介绍通过文件系统保存 ESP32 Web 的前端文件,然后在后端代码中引入 SPIFFS 文件系统。

2)通过在后端代码中新增 “/*” 通配符,实现所有未匹配到的 URL,都自动地去这个通配符对应的 handler 里去查找对应的文件,获取对应的数据。

资源链接

1)ESP32-Web-Server ESP-IDF系列博客介绍
2)对应示例的 code 链接 (点击直达代码仓库)

3)下一篇:ESP32-Web-Server 实战编程- 使用 AJAX 自动更新网页内容

(码字不易感谢点赞或收藏)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/181405.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Matplotlib直方图的创建_Python数据分析与可视化

Matplotlib直方图的创建 概念区分绘制直方图 概念区分 什么是直方图&#xff1f; 直方图&#xff08;Histogram&#xff09;又称质量分布图&#xff0c;是统计报告图的一种&#xff0c;由一系列高度不等的纵向条纹或线段表示数据分布的情况&#xff0c;一般用横轴表示数据所属…

解锁文件安全新境界!迅软DSE带您领略数据加密的魅力!

随着信息技术的不断发展&#xff0c;企业数据信息的安全与保护受到愈发广泛的关注。而文件加密软件得益于其强大的系统功能能够有效地保护企业重要数据的隐私和安全&#xff0c;成为越来越多企事业单位在进行内部数据安全防护工作时的优选。 一、文件加密软件的作用 文件加密软…

国产数据库

当今世界&#xff0c;数据已成为重要的生产要素&#xff0c;数据库管理系统更是广泛应用于信息化行业各领域&#xff0c;国内数据库产业能否健康可持续的发展&#xff0c;在很大程度上影响着国民经济发展和网络空间安全。 当前&#xff0c;国产数据库行业竞争非常激烈&#xf…

HCIE 01:基于前缀列表的BGP ORF功能

当运行BGP协议的某台设备上&#xff0c;针对入方向配置了基于ip-prefix的路由过滤&#xff0c;过滤了邻居发送的路由&#xff1b; 目前想&#xff0c;通过在peer关系的两端设备上都配置ORF功能&#xff0c;实现路由发送端只能送路由接收端过滤后的路由&#xff1b; ORF功能的说…

Leetcode—1670.设计前中后队列【中等】

2023每日刷题&#xff08;四十三&#xff09; Leetcode—1670.设计前中后队列 实现代码 erase(iterator position)在删除vector中的元素后&#xff0c;会将该元素的后面所有元素都往前挪一位。因此&#xff0c;原先的迭代器指向的元素就不是原来那个了&#xff0c;而是它的后…

2023年05月 Scratch图形化(四级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch等级考试(1~4级)全部真题・点这里 一、单选题(共10题,每题3分,共30分) 第1题 下列积木运行后的结果是?( )(说明:逗号后面无空格) A:我 B:爱 C:中 D:国 答案:B 两个字符串连接后的第8个字符是“爱”。 第2题 接鸡蛋游戏中,天空掉下来有鸡蛋、石…

Flink Flink中的合流

一、Flink中的基本合流操作 在实际应用中&#xff0c;我们经常会遇到来源不同的多条流&#xff0c;需要将它们的数据进行联合处理。所以 Flink 中合流的操作会更加普遍&#xff0c;对应的 API 也更加丰富。 二、联合&#xff08;Union&#xff09; 最简单的合流操作&#xf…

开源免费跨平台数据同步工具-Syncthing

Syncthing是一款开源免费跨平台的文件同步工具&#xff0c;是基于P2P技术实现设备间的文件同步&#xff0c;所以它的同步是去中心化的&#xff0c;即你并不需要一个服务器&#xff0c;故不需要担心这个中心的服务器给你带来的种种限制&#xff0c;而且类似于torrent协议&#x…

卡码网语言基础课 | 16. 出现频率最高的字母

目录 一、 哈希表 二、 编写解题 2.1 统计出现次数 2.2 解答 通过本次练习&#xff0c;将学习到C中哈希表的基础知识 题目&#xff1a; 给定一个只包含小写字母的字符串&#xff0c;统计字符串中每个字母出现的频率&#xff0c;并找出出现频率最高的字母&#xff0c;如果…

比尔盖茨:GPT-5不会比GPT-4好多少,生成式AI已达到极限

比尔盖茨一句爆料&#xff0c;成为机器学习社区热议焦点&#xff1a; “GPT-5不会比GPT-4好多少。” 虽然他已不再正式参与微软的日常运营&#xff0c;但仍在担任顾问&#xff0c;并且熟悉OpenAI领导团队的想法。 消息来自德国《商报》&#xff08;Handelsblatt&#xff09;对…

搞定这三个问题 伦敦金止损就没问题

笔者多次强调&#xff0c;做伦敦金交易&#xff0c;重要的是风险控制。而止损是我们风险控制中一个很重要的概念。设定好止损&#xff0c;就是风险控制的好开始。下面我们通过三个问题&#xff0c;来解决止损的问题。 问题一&#xff0c;你的止损位在哪里&#xff1f;要做止损&…

数据结构与算法之美学习笔记:27 | 递归树:如何借助树来求解递归算法的时间复杂度?

目录 前言递归树与时间复杂度分析实战一&#xff1a;分析快速排序的时间复杂度实战二&#xff1a;分析斐波那契数列的时间复杂度实战三&#xff1a;分析全排列的时间复杂度内容小结 前言 本节课程思维导图&#xff1a; 今天&#xff0c;我们来讲这种数据结构的一种特殊应用&am…

YOLO改进系列之SKNet注意力机制

摘要 视皮层神经元的感受野大小受刺激的调节即对于不同的刺激&#xff0c;卷积核的大小应该不同&#xff0c;但在构建CNN时一般在同一层只采用一种卷积核&#xff0c;很少考虑因采用不同卷积核。于是SKNet被提出&#xff0c;在SKNet中&#xff0c;不同大小的感受视野&#xff…

深度学习框架配置

目录 1. 配置cuda环境 1.1. 安装cuda和cudnn 1.1.1. 显卡驱动配置 1.1.2. 下载安装cuda 1.1.3. 下载cudnn&#xff0c;将解压后文件复制到cuda目录下 1.2. 验证是否安装成功 2. 配置conda环境 2.1. 安装anaconda 2.2. conda换源 2.3. 创建conda环境 2.4. pip换源 3.…

【工作记录】spider-flow使用插件连接并操作mongodb数据库

前言 前面说过&#xff0c;spider-flow有着非常优秀的插件机制&#xff0c;可以通过插件实现功能的扩展。前面有小伙伴问到mongodb的集成使用&#xff0c;本文就来梳理下spider-flow中使用mongodb插件的过程&#xff0c;其实非常简单。 PS: spider-flow的作者已经实现了一些常…

飞翔的小鸟小游戏

主类 package APP;import 框架.GameFrame;public class GameApp {public static void main(String[] args) {//游戏的入口new GameFrame();} }场景实物 package 框架;import 图导.Constant; import 图导.GameUtil;import java.awt.*; import java.awt.image.BufferedImage; …

C语言——数字金字塔

实现函数输出n行数字金字塔 #define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>void pyramid(int n) {int i,j,k;for (i1; i<n; i){//输出左边空格&#xff0c;空格数为n-i for (j1; j<n-i; j){printf(" "); } //每一行左边空格输完后输出数字&#…

STM32g70开启定时器死机原因

在做低功耗产品时&#xff0c;检查发现由于之前开启了BOOTLOADER升级程序&#xff0c;修改了中断向量FALSH起始地址&#xff0c;只在KEIL TARGET IROM1中修改了&#xff0c; 而忘记在程序文件system_stm32f10x.c里修改中断向量表flash起始地址 system_stm32f10x.c里&#xff0…

8款前端特效动画及源码分享

3D立体数字时钟滚动特效 基于Splitting制作的一款3D立体数字时钟滚动特效&#xff0c;创意感满满&#xff0c;可以下载使用。 预览获取 核心代码 <div class"clock"><span class"cog hours tens" data-splitting>0123456789</span>&l…

智能优化算法应用:基于鸡群算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于鸡群算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于鸡群算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.鸡群算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…