【花雕学编程】Arduino HTTP 之ESP32的HTTP GET 和 HTTP POST_gbrl-esp32
《Arduino 手册(思路与案例)》栏目介绍:
在电子制作与智能控制的应用领域,本栏目涵盖了丰富的内容,包括但不限于以下主题:Arduino BLDC、Arduino CNC、Arduino E-Ink、Arduino ESP32 SPP、Arduino FreeRTOS、Arduino FOC、Arduino GRBL、Arduino HTTP、Arduino HUB75、Arduino IoT Cloud、Arduino JSON、Arduino LCD、Arduino OLED、Arduino LVGL、Arduino PID、Arduino TFT,以及Arduino智能家居、智慧交通、月球基地、智慧校园和智慧农业等多个方面与领域。不仅探讨了这些技术的基础知识和应用领域,还提供了众多具体的参考案例,帮助读者更好地理解和运用Arduino平台进行创新项目。目前,本栏目已有近4000篇相关博客,旨在为广大电子爱好者和开发者提供全面的学习资源与实践指导。通过这些丰富的案例和思路,读者可以获取灵感,推动自己的创作与开发进程。
https://blog.csdn.net/weixin_41659040/category_12422453.html
Arduino HTTP 之 ESP32 的 HTTP GET 和 HTTP POST
一、主要特点
HTTP GET 请求:
数据请求:HTTP GET 请求主要用于从服务器获取数据,常用于请求资源,如网页、API 数据等。
参数传递:通过 URL 查询字符串传递参数,适合传递小量数据(如搜索关键词、过滤条件等)。
无副作用:GET 请求一般被视为安全的,不会对服务器状态造成影响,适合用于获取信息。
HTTP POST 请求:
数据提交:HTTP POST 请求用于向服务器发送数据,适合提交表单数据、上传文件等。
请求体传递:数据通过请求体传递,可以发送大量数据,适合复杂数据结构(如 JSON、XML)。
有副作用:POST 请求可能会改变服务器的状态,适用于数据创建、更新等操作。
二、应用场景
物联网设备:
GET 请求:用于获取传感器数据或设备状态,用户可以实时监测设备信息。
POST 请求:用于发送传感器采集的数据到服务器,进行数据存储和分析。
智能家居控制:
GET 请求:用户可以通过 GET 请求获取家庭设备的当前状态(如灯光、温度等)。
POST 请求:用户可以通过 POST 请求修改设备设置(如调节灯光亮度、温度设置等)。
移动应用与网页应用:
GET 请求:用于加载数据(如用户信息、商品列表)以供展示。
POST 请求:用于用户注册、登录或提交评论、反馈等操作。
远程监控与管理:
GET 请求:获取设备的实时监控数据(如摄像头画面、报警状态)。
POST 请求:发送控制指令(如开关设备、调整设置)到远程设备。
数据采集与分析:
GET 请求:用于查询历史数据或统计信息。
POST 请求:将采集的数据发送到云端进行分析和存储。
三、注意事项
数据安全性:
对于敏感数据,建议使用 HTTPS 协议加密传输,以防数据被窃取或篡改。
参数有效性验证:
在处理 GET 和 POST 请求时,需验证传入参数的有效性和完整性,避免因无效数据导致的错误。
请求体限制:
POST 请求虽然可以发送大量数据,但仍需考虑服务器的请求体大小限制,避免超出限制导致请求失败。
网络稳定性:
ESP32 设备的 HTTP 请求依赖于网络连接,网络不稳定可能导致请求失败或响应延迟,需考虑网络环境的可靠性。
错误处理机制:
在实现 GET 和 POST 请求时,需设计完善的错误处理机制,以便处理网络错误、超时等异常情况,提升系统的健壮性。
1、HTTP GET 请求示例
#include #include const char* ssid = \"your_SSID\"; // WiFi 名称const char* password = \"your_PASSWORD\"; // WiFi 密码void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println(\"连接中...\"); } Serial.println(\"WiFi 连接成功\");}void loop() { if (WiFi.status() == WL_CONNECTED) { HTTPClient http; http.begin(\"http://example.com/api/data\"); // 目标 URL int httpResponseCode = http.GET(); // 发送 GET 请求 if (httpResponseCode > 0) { String payload = http.getString(); // 获取响应数据 Serial.println(\"响应代码: \" + String(httpResponseCode)); Serial.println(\"响应内容: \" + payload); } else { Serial.println(\"请求失败,错误代码: \" + String(httpResponseCode)); } http.end(); // 结束 HTTP 请求 } delay(10000); // 每10秒请求一次}
2、HTTP POST 请求示例
#include #include const char* ssid = \"your_SSID\"; const char* password = \"your_PASSWORD\"; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println(\"连接中...\"); } Serial.println(\"WiFi 连接成功\");}void loop() { if (WiFi.status() == WL_CONNECTED) { HTTPClient http; http.begin(\"http://example.com/api/data\"); // 目标 URL // 设置请求头 http.addHeader(\"Content-Type\", \"application/json\"); // JSON 数据 String jsonData = \"{\\\"temperature\\\": 25, \\\"humidity\\\": 60}\"; int httpResponseCode = http.POST(jsonData); // 发送 POST 请求 if (httpResponseCode > 0) { String payload = http.getString(); // 获取响应数据 Serial.println(\"响应代码: \" + String(httpResponseCode)); Serial.println(\"响应内容: \" + payload); } else { Serial.println(\"请求失败,错误代码: \" + String(httpResponseCode)); } http.end(); // 结束 HTTP 请求 } delay(10000); // 每10秒发送一次数据}
3、综合使用 GET 和 POST 请求
#include #include const char* ssid = \"your_SSID\"; const char* password = \"your_PASSWORD\"; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println(\"连接中...\"); } Serial.println(\"WiFi 连接成功\");}void loop() { // 发送 GET 请求 if (WiFi.status() == WL_CONNECTED) { HTTPClient http; http.begin(\"http://example.com/api/data\"); int httpResponseCode = http.GET(); if (httpResponseCode > 0) { String payload = http.getString(); Serial.println(\"GET 响应代码: \" + String(httpResponseCode)); Serial.println(\"GET 响应内容: \" + payload); } else { Serial.println(\"GET 请求失败,错误代码: \" + String(httpResponseCode)); } // 发送 POST 请求 http.addHeader(\"Content-Type\", \"application/json\"); String jsonData = \"{\\\"temperature\\\": 25, \\\"humidity\\\": 60}\"; httpResponseCode = http.POST(jsonData); if (httpResponseCode > 0) { String payload = http.getString(); Serial.println(\"POST 响应代码: \" + String(httpResponseCode)); Serial.println(\"POST 响应内容: \" + payload); } else { Serial.println(\"POST 请求失败,错误代码: \" + String(httpResponseCode)); } http.end(); // 结束 HTTP 请求 } delay(10000); // 每10秒发送一次数据}
要点解读
WiFi 连接:
所有示例首先通过 WiFi.begin() 连接到指定的 WiFi 网络。使用 while 循环等待连接成功,确保设备能够访问互联网,这是实现 HTTP 请求的基础。
HTTPClient 类的使用:
使用 HTTPClient 类来处理 HTTP 请求。通过 http.begin() 设置目标 URL,并使用 http.GET() 或 http.POST() 发送请求。这种机制使得 ESP32 能够与远程服务器进行通信。
请求头和数据格式:
在 POST 请求中,使用 http.addHeader() 设置请求头,如 Content-Type 为 application/json,以告知服务器发送的数据格式。在发送 JSON 数据时,确保数据符合 JSON 格式,以便服务器能够正确解析。
响应处理:
通过 http.getString() 获取响应内容,并根据返回的状态码进行处理。如果请求成功,输出响应内容;如果失败,输出错误代码。这增强了程序的健壮性,确保用户能够得到反馈。
定时请求:
在 loop() 函数中,使用 delay(10000) 控制请求频率,避免频繁请求导致的网络负担。每10秒发送一次请求,适用于周期性数据收集或状态监测的场景。
4、基础HTTP GET请求(获取天气数据)
#include #include const char* ssid = \"Your_WiFi_SSID\";const char* password = \"Your_WiFi_PASSWORD\";const String apiKey = \"YOUR_OPENWEATHERMAP_KEY\";const String city = \"Beijing\"; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) delay(500); Serial.println(\"WiFi Connected\");} void loop() { if (WiFi.status() == WL_CONNECTED) { HTTPClient http; String url = \"http://api.openweathermap.org/data/2.5/weather?q=\" + city + \"&appid=\" + apiKey; http.begin(url); int httpCode = http.GET(); // 发送GET请求 if (httpCode > 0) { String payload = http.getString(); Serial.println(\"Weather Data: \" + payload); } else { Serial.println(\"HTTP Error: \" + String(httpCode)); } http.end(); } delay(60000); // 每分钟请求一次}
关键点:
使用HTTPClient库简化HTTP请求流程。
GET请求参数通过URL拼接(如?key=value)。
必须调用http.end()释放资源。
实际应用中需处理JSON解析(如ArduinoJson库)。
避免频繁请求(如案例中的60秒间隔),防止被API限流。
5、HTTP POST提交传感器数据(JSON格式)
#include #include #include const char* ssid = \"Your_WiFi_SSID\";const char* password = \"Your_WiFi_PASSWORD\";const String serverUrl = \"http://your-server.com/api/data\"; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) delay(500);} void loop() { if (WiFi.status() == WL_CONNECTED) { HTTPClient http; http.begin(serverUrl); http.addHeader(\"Content-Type\", \"application/json\"); // 模拟传感器数据 DynamicJsonDocument doc(256); doc[\"temperature\"] = 25.5; doc[\"humidity\"] = 60; String jsonStr; serializeJson(doc, jsonStr); int httpCode = http.POST(jsonStr); // 发送POST请求 if (httpCode == HTTP_CODE_OK) { String response = http.getString(); Serial.println(\"Server Response: \" + response); } else { Serial.println(\"HTTP Error: \" + String(http.errorToString(httpCode).c_str())); } http.end(); } delay(5000); // 每5秒提交一次}
关键点:
POST请求需设置Content-Type头(如application/json)。
使用ArduinoJson库构造JSON数据体。
检查http.errorToString()获取详细错误信息。
服务器端需配置接收JSON的接口(如Node.js/Express)。
生产环境建议添加HTTPS支持(http.begin(url, fingerprint))。
6、带认证的HTTP POST(Basic Auth)
#include #include #include // 需安装Base64库 const char* ssid = \"Your_WiFi_SSID\";const char* password = \"Your_WiFi_PASSWORD\";const String serverUrl = \"http://your-server.com/api/secure\";const String username = \"admin\";const String apiPassword = \"secure123\"; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) delay(500);} void loop() { if (WiFi.status() == WL_CONNECTED) { HTTPClient http; http.begin(serverUrl); // 生成Basic Auth头 String auth = username + \":\" + apiPassword; String encodedAuth = base64::encode(auth); http.addHeader(\"Authorization\", \"Basic \" + encodedAuth); // 提交数据 String postData = \"device=esp32&value=100\"; int httpCode = http.POST(postData); if (httpCode > 0) { Serial.println(\"Response: \" + http.getString()); } else { Serial.println(\"Error: \" + http.errorToString(httpCode)); } http.end(); } delay(10000);}
关键点:
Basic Auth通过Authorization头传递凭证(格式:Basic Base64(username:password))。
使用base64库编码凭证(注意:HTTPS更安全)。
可结合案例2的JSON数据体扩展功能。
服务器端需验证授权头(如Nginx的auth_basic或自定义中间件)。
敏感信息(如密码)建议存储在ESP32的NVS(非易失性存储)中。
五点通用要点解读
网络连接管理
必须检查WiFi.status(),避免断网时崩溃。
考虑使用WiFi.setAutoReconnect(true)自动重连。
错误处理
检查httpCode是否为HTTP_CODE_OK(200)。
超时设置:http.setTimeout(5000)(默认5秒)。
性能优化
复用HTTPClient对象(如全局声明)减少内存开销。
长连接:服务器需支持Connection: keep-alive。
安全建议
敏感数据(如API Key)避免硬编码,使用环境变量或加密存储。
重要操作建议改用HTTPS(需服务器证书指纹)。
调试技巧
通过Serial.println(http.getString())打印原始响应。
使用工具(如Postman)先测试服务器接口是否正常。
注意,以上案例只是为了拓展思路,仅供参考。它们可能有错误、不适用或者无法编译。您的硬件平台、使用场景和Arduino版本可能影响使用方法的选择。实际编程时,您要根据自己的硬件配置、使用场景和具体需求进行调整,并多次实际测试。您还要正确连接硬件,了解所用传感器和设备的规范和特性。涉及硬件操作的代码,您要在使用前确认引脚和电平等参数的正确性和安全性。