ESP32-Web-Server编程- 通过文本框向 Web 提交数据
概述
前述章节我们通过简单 HTML、AJAX、Websocket、SSE 在网页上显示数据,通过网页上的按钮控制 ESP32 的行为。从本节开始,我们将进一步了解通过网页与 ESP32 进行交互的方法。
实现更复杂的交互功能,从通过网页向 ESP32 发送字符串、数字开始。ESP32 在接收到这些字符串时可以识别其含义,实现对 ESP32 的灵活的控制。这就是物联网的简单的项目原型了。
需求及功能解析
本节演示如何在 ESP32 上部署一个 Web 服务器,并在访问该 web 服务器时在网页端提供一个字符串输入框、数字输入框。可以在网页输入对应的字符、数字到 ESP32 的 Web 服务器。
示例解析
目录结构
├── CMakeLists.txt
├── main
│ ├── CMakeLists.txt
│ └── main.c User application
├── components
│ └── fs_image
└── README.md This is the file you are currently reading
- 目录结构主要包含主目录 main,以及组件目录 components.
- 其中组件目录components中包含了用于存储网页文件的 fs_image 目录(即前述前端文件)。
前端代码
前端代码的 HTML 部分在 components/fs_image/web_image/index.html
中,创建了两个 input 输入框,类型分别是 Text Field
、Text Field
,它们分别用于输入字符串、数字。
<div class="card">
<form action="/" method="POST">
<p class="card-title">Text Field</p>
<p>
<label for="input1">Input 1</label>
<input type="text" id ="input1" name="input1">
<input type ="submit" value ="Submit">
</p>
</form>
</div>
<div class="card">
<form action="/" method="POST">
<p class="card-title">Number Field</p>
<p>
<label for="input2">Input 2</label>
<input type="number" id ="input2" name="input2">
<input type ="submit" value ="Submit">
</p>
</form>
此外,在网页上还增加了实时显示当前值的两个显示文本,分别显示当前 ESP32 上字符串、数字的值:
<div class="card">
<p class="card-title">Text Value</p>
<p class="value">Current value: <span id="textFieldValue"></span></p>
</div>
<div class="card">
<p class="card-title">Number Value</p>
<p class="value">Current value: <span id="numberFieldValue"></span></p>
</div>
它们通过 components/fs_image/web_image/js/script.js 中的 getValues()
来获得更新:
// Function to get current readings on the webpage when it loads/refreshes
function getValues(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myObj = JSON.parse(this.responseText);
console.log(myObj);
document.getElementById("textFieldValue").innerHTML = myObj.textValue;
document.getElementById("numberFieldValue").innerHTML = myObj.numberValue;
}
};
xhr.open("GET", "/values", true);
xhr.send();
}
后端代码
后端代码主要是增加了浏览器通过网页向服务器推送数据时的处理函数update_values_post_handler():
{"/", HTTP_POST, update_values_post_handler, rest_context},
在该函数中,接收推动数据,并解析推送数据中的字符串和数字:
/* Simple handler for uart_info_post handler */
static esp_err_t update_values_post_handler(httpd_req_t* req)
{
ESP_LOGD(TAG, "in / post handler");
char filepath[FILE_PATH_MAX];
rest_server_context_t* rest_context = (rest_server_context_t*) req->user_ctx;
char* buf = ((rest_server_context_t*) (req->user_ctx))->scratch;
int str_len = 0;
char temp_str[128] = {0};
if (recv_post_data(req, buf) != ESP_OK) {
// modbus_dtu_web_response_error(req, HTTPD_500);
ESP_LOGE(TAG, "recv post data error");
return ESP_FAIL;
}
str_len = httpd_find_arg(buf, my_para1, temp_str, sizeof(temp_str));
if ((str_len != -1) && (strlen((char *)temp_str) != 0)) {
memcpy(my_str, temp_str, strlen(temp_str)+1);
ESP_LOGI(TAG, "updates:str=%s", my_str);
}
memset(temp_str, '\0', sizeof(temp_str));
str_len = httpd_find_arg(buf, my_para2, temp_str, sizeof(temp_str));
if ((str_len != -1) && (strlen((char *)temp_str) != 0)) {
my_num = atoi(temp_str);
ESP_LOGI(TAG, "updates:num=%d", my_num);
}
// return index html file
strlcpy(filepath, rest_context->base_path, sizeof(filepath));
strlcat(filepath, "/index.html", sizeof(filepath));
if(custom_send_file_chunk(req, filepath) != ESP_OK) {
ESP_LOGE(TAG, "rest common send err");
return ESP_FAIL;
}
return ESP_OK;
}
注意,每次更新值,我们都重新返回整个 html 文件,以便于可以触发components/fs_image/web_image/js/script.js 中的 getValues()
,在网页上更新当前下发数据的值。
示例效果
讨论
1)这是我们首次使用 HTTP 的 POST 方法,可以参考 A 回顾 HTTP 的基本方法。我们将在后续的章节掌握更多有趣且使用的开发技能。
总结
1)本节主要是介绍在 ESP32 Web 上部署带输入文本框的网页,通过网页向 ESP32 发送字符串和数字。通过这种机制,我们可以实现对 ESP32 简单的数据通信。
资源链接
1)ESP32-Web-Server ESP-IDF系列博客介绍
2)对应示例的 code 链接 (点击直达代码仓库)
3)下一篇:ESP32-Web-Server编程- 通过滑动条向 Web 提交数据
(码字不易感谢点赞或收藏)