ESP8266+httpServer+GET+POST实现网页验证密码

1. 代码

#include "esp_http_server.h"
#include "esp_log.h"
#include "web_server.h"// 辅助宏,用于计算两个数中的较小值
#define MIN(a, b) ((a) < (b) ? (a) : (b))static const char *TAG = "wifi web_server";const char login_page[] = {"\
<!DOCTYPE html>\
<html>\
<head>\
<meta charset='UTF-8'>\
<title>Sensor Configuration</title>\
</head>\
<body>\
<form method='POST' action='login.html'>\
<br>\
<P align=center style='color:#0066ff'><b>Sensor</b></P>\
<br><br>\
<P align=center>登录密码:&nbsp&nbsp&nbsp&nbsp;<input name=PASSWORD type=password size=18 maxlength=15></P>\
<br>\
<P align=center><input type=submit value='进入'></P>\
</form>\
</body>\
</html>\
"};const char str_password_ok[] = "Password validated successfully";
const char str_password_ng[] = "Invalid password";
const char str_password_lost[] = "Missing PASSWORD field";// HTTP服务器配置
esp_err_t http_get_handler(httpd_req_t *req)
{
//    const char* resp_str = "<html><body><h1>Hello ESP8266!</h1></body></html>";const char* resp_str = login_page;ESP_LOGI(TAG, "send login html");httpd_resp_send(req, resp_str, strlen(resp_str));return ESP_OK;
}// 预期的密码
static const char *expected_password = "88888";// 用于存储从请求体中读取的数据(注意:这里使用了固定大小)
#define REQUEST_BODY_MAX_SIZE 1024
static char request_body[REQUEST_BODY_MAX_SIZE] = {0};
static size_t request_body_len = 0;// 辅助函数:从请求中读取数据(使用固定大小缓冲区)
static esp_err_t read_request_body(httpd_req_t *req) {//char buffer[128]; // 临时缓冲区,小于总缓冲区大小int len;// 循环读取请求体数据,直到没有更多数据可读或缓冲区满len = httpd_req_recv(req, request_body, REQUEST_BODY_MAX_SIZE - 1);if (len == HTTPD_SOCK_ERR_TIMEOUT) {// 超时错误处理ESP_LOGE("http_server", "Read timeout");return ESP_ERR_TIMEOUT;} else if (len < 0) {// 读取错误处理ESP_LOGE("http_server", "Error reading request body");return ESP_FAIL;}// 确保字符串以 null 结尾request_body[len] = '\0';request_body_len = len; // 更新请求体长度return ESP_OK;
}esp_err_t http_post_handler(httpd_req_t *req) {// 重置请求体缓冲区memset(request_body, 0, REQUEST_BODY_MAX_SIZE);request_body_len = 0;// 读取整个请求体if (read_request_body(req) != ESP_OK) {// 读取请求体时发生错误httpd_resp_send_500(req);return ESP_FAIL;}// 假设请求体是 URL 编码的,并且包含 PASSWORD=...char *password_start = strstr(request_body, "PASSWORD=");if (password_start != NULL) {password_start += strlen("PASSWORD=");char *password_end = strchr(password_start, '&'); // 查找下一个字段的开始或字符串末尾if (password_end == NULL) {password_end = password_start + strlen(password_start); // 如果没有 '&',则指向末尾}// 计算密码长度(注意:这里要防止越界)size_t password_len = MIN(password_end - password_start, strlen(expected_password));// 比较密码if (strncmp(password_start, expected_password, password_len) == 0 &&(password_len == strlen(expected_password) || *(password_end - 1) == '&')) {httpd_resp_send(req, str_password_ok,strlen(str_password_ok));      //HTTP_OK} else {httpd_resp_send(req, str_password_ng,strlen(str_password_ng));  //HTTP_UNAUTHORIZED,}} else {httpd_resp_send(req, str_password_lost,strlen(str_password_lost));  //HTTP_BAD_REQUEST,}return ESP_OK;
}httpd_handle_t start_webserver(void)
{httpd_handle_t server = NULL;httpd_config_t config = HTTPD_DEFAULT_CONFIG();// GET 请求处理httpd_uri_t get_uri  = {.uri       = "/",.method    = HTTP_GET,.handler   = http_get_handler,.user_ctx  = NULL};// POST 请求处理(注意:这里假设表单提交到 /login)httpd_uri_t post_uri = {.uri       = "/login.html",.method    = HTTP_POST,.handler   = http_post_handler,.user_ctx  = NULL};// 启动HTTP服务器if (httpd_start(&server, &config) == ESP_OK) {ESP_LOGI(TAG, "Server started");if (httpd_register_uri_handler(server, &get_uri) != ESP_OK) {ESP_LOGE(TAG, "Failed to register GET URI handler");}if (httpd_register_uri_handler(server, &post_uri) != ESP_OK) {ESP_LOGE(TAG, "Failed to register POST URI handler");}} else {ESP_LOGE(TAG, "Failed to start server");}return server;
}

2 . 密码错误、正确的网页效果

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

自己看---分披萨

题目描述 "吃货"和"馋嘴"两人到披萨店点了一份铁盘&#xff08;圆形&#xff09;披萨&#xff0c;并嘱咐店员将披萨按放射状切成大小相同的偶数个小块。但是粗心的服务员将披萨切成了每块大小都完全不同奇数块&#xff0c;且肉眼能分辨出大小。 由于两人都…

安卓BLE蓝牙通讯

蓝牙测试demo 简介   Android手机间通过蓝牙方式进行通信&#xff0c;有两种常见的方式&#xff0c;一种是socket方式&#xff08;传统蓝牙&#xff09;&#xff0c;另一种是通过GATT&#xff08;BLE蓝牙&#xff09;。与传统蓝牙相比&#xff0c;BLE 旨在大幅降低功耗。这样…

华为OD机试 - 推荐多样性(Python/JS/C/C++ 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…

气压测试实验(用IIC)

I2C: 如果没有I2c这类总线&#xff0c;连接方法可能会如下图&#xff1a; 单片机所有的通讯协议&#xff0c;无非是建立在引脚&#xff08;高低电平的变换高低电平持续的时间&#xff09;这二者的组合上&#xff0c;i2c 多了一个clock线&#xff0c;负责为数据传输打节拍。 (i2…

C#使用TCP-S7协议读写西门子PLC(四)

接上一篇,我们连接PLC并握手成功,并且封装生成读写PLC的命令 C#使用TCP-S7协议读写西门子PLC(三)-CSDN博客 这里我们进行读写基础数据类型、读取DB块的字符串、宽字符串、以及一系列连续数组。 新建部分类文件SiemensS7ProtocolUtil.Integrated.cs 主要方法 读取任意连续…

C和指针:函数

函数定义 函数体就是一个代码块&#xff0c;它在函数被调用时执行。 类型 函数名(形式参数) 代码块 与函数定义相反&#xff0c;函数声明出现在函数被调用的地方。 函数声明 编译器是如何知道该函数期望接受的是什么类型和多少数量的参数。 原型 int *find_int( int key…

ASPICE评估全流程解析:汽车软件开发组织能力的系统化评估

ASPICE&#xff08;Automotive SPICE&#xff09;评估的过程是一个系统化和详尽的流程&#xff0c;旨在评估汽车软件开发组织在软件开发过程方面的能力。 以下是ASPICE评估过程的详细描述&#xff1a; 1. 评估准备阶段 a. 确定评估目标和范围 明确评估的目标&#xff0c;如评…

同时拥有独显和核显,怎么让应用程序选择使用哪个GPU?

看你现在使用的是核显还是独显 勾选上GPU引擎选项&#xff0c;后面便会标识你所使用的是哪种显卡&#xff0c;如果是独立显卡&#xff0c;就可以免去后续的操作&#xff1b;如果不是&#xff0c;那么请继续接下来的操作。 将你需要使用独显的程序换成gpu1&#xff08;独显&am…

Spring Boot 注解探秘:JSON 处理的魔法世界

Spring Boot 注解探秘&#xff1a;JSON 处理的魔法世界 首发2024-09-11 16:43潘多编程 在当今这个数据驱动的世界里&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;已经成为了数据交换的事实标准。无论是前端与后端的通信&#xff0c;还是系统间的服务交…

C# List定义和常用方法

栏目总目录 List的定义 列表&#xff08;List&#xff09;是一种常用的集合类型&#xff0c;它属于System.Collections.Generic命名空间。列表是一个有序集合&#xff0c;可以包含重复的元素&#xff0c;并且可以根据索引访问元素。 List< T > List<T> 是一个泛…

佰朔资本:未来钢铁行业产业格局有望稳中趋好

组织指出&#xff0c;未来钢铁作业工业格式有望稳中趋好&#xff0c;叠加当时部分公司已经处于价值小看区域&#xff0c;现阶段仍具结构性出资机会&#xff0c;尤其是拥有较高毛利率水平的优特钢企业和本钱管控力度强、具有规划效应的龙头钢企&#xff0c;未来存在估值修改的机…

git submodule sync

git submodule 是 Git 提供的一种功能&#xff0c;用于在一个 Git 仓库中嵌套另一个 Git 仓库。它可以帮助管理和跟踪外部项目或依赖项&#xff0c;特别是在以下场景中非常有用&#xff1a; 1. 管理外部依赖 当你的项目依赖于其他外部项目或库时&#xff0c;可以使用 git sub…

JavaEE:文件操作

文章目录 文件操作和IO文件系统操作File介绍属性构造方法方法 代码演示前四个listmkdirrenameTo 文件操作和IO 文件系统操作 创建文件,删除文件,创建目录,重命名… Java中有一个类,可以帮我们完成上述操作. 这个类叫做File类. File介绍 属性 这个表格描述了文件路径的分隔符…

应急响应实战---是谁修改了我的密码?

前言&#xff1a;此次应急响应为真实案例&#xff0c;客户反馈无法通过密码登录服务器&#xff0c;疑似服务器被入侵 0x01 如何找回密码&#xff1f; 客户服务器为windows server2019&#xff0c;运维平台为PVE平台&#xff1b;实际上无论是windows系统或者是linux系统&#…

ROS2 Control controller_interface说明

ROS2 Control controller_interface说明 文章目录 前言controller_interface说明Class ControllerInterfaceBaseClass ControllerInterface说明Class ChainableControllerInterface说明 semantic_components说明Class ForceTorqueSensorClass IMUSensorClass RangeSensor 参考 …

Jacoco的XML报告详解

使用jacococli完成jacoco测试报告生成后,会看到有一个.xml结尾的文件,这个就是xml格式的覆盖率报告。除了xml还有csv、html格式的报告,本文进介绍xml报告。 DTD文件 在介绍jacoco的xml报告之前,我们应该先看一下对应的DTD文件的内容。(DTD的全称为Document Type Definitio…

Java应用的数据库连接池连接池性能测试

Java应用的数据库连接池连接池性能测试 大家好&#xff0c;我是微赚淘客返利系统3.0的小编&#xff0c;是个冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 数据库连接池的性能测试是确保Java应用能够高效运行的关键步骤。性能测试可以帮助我们评估连接池在高并发…

Rust 所有权 借用与引用

文章目录 发现宝藏1. 所有权&#xff08;Ownership&#xff09;2. 引用&#xff08;References&#xff09;2.1 不可变引用2.2 可变引用2.3 引用的规则 3. 悬垂引用&#xff08;Dangling References&#xff09;4. 借用&#xff08;Borrowing&#xff09;结论 发现宝藏 前些天…

个人学习笔记7-5:动手学深度学习pytorch版-李沐

#人工智能# #深度学习# #语义分割# #计算机视觉# #神经网络# 计算机视觉 13.10 转置卷积 例如&#xff0c;卷积层和汇聚层&#xff0c;通常会减少下采样输入图像的空间维度&#xff08;高和宽&#xff09;。然而如果输入和输出图像的空间维度相同&#xff0c;在以像素级分类…

【App】React Native

React Native 的优势&#xff1a; 开发体验好 用统一的代码规范开发移动端程序&#xff0c;不用关注移动端的差异.开发成本低 开发一次&#xff0c;可以生成 Android 和 IOS 俩个系统上的 App学习成本低 只要掌握 JavaScript 和 React 就可以进行移动端开发 React Native 的不…