目的
很多时候我们需要ESP32去访问外网的服务器,HTTP服务器是最常见的服务器,在这个时候就需要ESP32作为HTTPClient使用,这篇文章将对相关内容做个说明。
基础说明
HTTPClient从原理角度来说使用并不复杂,主要步骤如下:
- 引用库
#include <HTTPClient.h>
; - 连上网;
- 声明
HTTPClient
对象; - 使用
begin()
方法准备要访问的url
; - 填写请求头内容(如果需要的话);
- 发起
GET
、POST
等请求,并接收返回的状态码; - 根据需求读取响应头或响应正文内容;
- 使用
end()
方法结束当前连接;
使用演示
示例一
#include <WiFi.h>
#include <HTTPClient.h>
const char *ssid = "********"; //你的网络名称
const char *password = "********"; //你的网络密码
void setup()
{
Serial.begin(115200);
Serial.println();
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected!");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void loop()
{
HTTPClient http; // 声明HTTPClient对象
http.begin("http://example.com/index.html"); // 准备启用连接
int httpCode = http.GET(); // 发起GET请求
if (httpCode > 0) // 如果状态码大于0说明请求过程无异常
{
if (httpCode == HTTP_CODE_OK) // 请求被服务器正常响应,等同于httpCode == 200
{
String payload = http.getString(); // 读取服务器返回的响应正文数据
// 如果正文数据很多该方法会占用很大的内存
Serial.println(payload);
}
}
else
{
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end(); // 结束当前连接
delay(10000);
}
示例二
#include <WiFi.h>
#include <HTTPClient.h>
const char *ssid = "********"; //你的网络名称
const char *password = "********"; //你的网络密码
void setup()
{
Serial.begin(115200);
Serial.println();
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected!");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void loop()
{
HTTPClient http; // 声明HTTPClient对象
http.begin("http://example.com/index.html"); // 准备启用连接
int httpCode = http.GET(); // 发起GET请求
if (httpCode > 0) // 如果状态码大于0说明请求过程无异常
{
if (httpCode == HTTP_CODE_OK) // 请求被服务器正常响应,等同于httpCode == 200
{
uint8_t buff[128] = {0};
int len = http.getSize(); // 读取响应正文数据字节数,如果返回-1是因为响应头中没有Content-Length属性
WiFiClient *stream = http.getStreamPtr(); // 获取响应正文数据流指针
while (http.connected() && (len > 0 || len == -1)) // 当前已连接并且有数据可读
{
size_t size = stream->available(); // 获取数据流中可用字节数
if (size)
{
int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size)); // 读取数据到buff
Serial.write(buff, c);
if (len > 0)
{
len -= c;
}
}
delay(1);
}
}
}
else
{
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end(); // 结束当前连接
delay(10000);
}
示例三
#include <WiFi.h>
#include <HTTPClient.h>
const char *ssid = "********"; //你的网络名称
const char *password = "********"; //你的网络密码
void setup()
{
Serial.begin(115200);
Serial.println();
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected!");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
const char *headerKeys[] = {"Content-Type", "Content-Length"};
void loop()
{
HTTPClient http; // 声明HTTPClient对象
http.begin("http://example.com/index.html"); // 准备启用连接
http.collectHeaders(headerKeys, 2); // 准备需要接收的响应头内容
int httpCode = http.GET(); // 发起GET请求
if (httpCode > 0) // 如果状态码大于0说明请求过程无异常
{
if (httpCode == HTTP_CODE_OK) // 请求被服务器正常响应,等同于httpCode == 200
{
Serial.print("Content-Type = ");
Serial.println(http.header("Content-Type"));
Serial.print("Content-Length = ");
Serial.println(http.header("Content-Length"));
}
}
else
{
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end(); // 结束当前连接
delay(10000);
}
库说明
方法说明
HTTPClient的一些公共的方法如下:
-
bool begin(WiFiClient &client, String url)
bool begin(WiFiClient &client, String host, uint16_t port, String uri = "/", bool https = false)
设置连接某个url; -
bool begin(String url)
bool begin(String url, const char* CAcert)
bool begin(String host, uint16_t port, String uri = "/")
bool begin(String host, uint16_t port, String uri, const char* CAcert)
bool begin(String host, uint16_t port, String uri, const char* CAcert, const char* cli_cert, const char* cli_key)
同上,需要支持HTTP1.1; -
void setReuse(bool reuse)
设置请求头中的keep-alive,默认为true; -
void setUserAgent(const String& userAgent)
设置请求头中的User-Agent; -
void setAuthorization(const char * user, const char * password)
void setAuthorization(const char * auth)
设置请求头中的Authorization; -
void addHeader(const String& name, const String& value, bool first = false, bool replace = true)
向请求头添加自定义字段; -
void setConnectTimeout(int32_t connectTimeout)
设置与服务器建立连接的超时时间; -
void setTimeout(uint16_t timeout)
设置TCP连接的超时时间; -
void setFollowRedirects(followRedirects_t follow)
设置http连接重定向处理方式,可选值如下:
HTTPC_DISABLE_FOLLOW_REDIRECTS
默认值,不进行重定向
HTTPC_STRICT_FOLLOW_REDIRECTS
只有使用GET或HEAD方法的请求将被重定向
HTTPC_FORCE_FOLLOW_REDIRECTS
进行重定向 -
void setRedirectLimit(uint16_t limit)
单个请求重定向最大次数,默认为10; -
bool setURL(const String &url)
重新设置url; -
void useHTTP10(bool usehttp10 = true)
设置http协议版本,未调用该方法时默认为false,即默认使用HTTP1.1; -
int GET()
向服务器发起GET请求,并返回状态码或错误代码; -
int PATCH(uint8_t * payload, size_t size)
int PATCH(String payload)
向服务器发起PATCH请求,并返回状态码或错误代码;
payload为请求的body中的内容; -
int POST(uint8_t * payload, size_t size)
int POST(String payload)
向服务器发起POST请求,并返回状态码或错误代码;
payloadw为请求的body中的内容; -
int PUT(uint8_t * payload, size_t size)
int PUT(String payload)
向服务器发起PUT请求,并返回状态码或错误代码;
payloadw为请求的body中的内容; -
int sendRequest(const char * type, String payload)
int sendRequest(const char * type, uint8_t * payload = NULL, size_t size = 0)
int sendRequest(const char * type, Stream * stream, size_t size = 0)
向服务器发起请求,并返回状态码或错误代码; -
bool connected(void)
返回当前是否建立连接; -
void collectHeaders(const char* headerKeys[], const size_t headerKeysCount)
设置需要获取的响应头键名与键值对数量; -
int headers()
返回响应头键值对数量;(需要先设置collectHeaders) -
bool hasHeader(const char* name)
查询响应头是否存在某个键值对;(需要先设置collectHeaders) -
String header(const char* name)
返回响应头某个键对应的值;(需要先设置collectHeaders) -
String header(size_t i)
以headerKeys数组编号返回响应头的键对应的值;(需要先设置collectHeaders) -
String headerName(size_t i)
以headerKeys数组编号返回键名称; -
const String &getLocation(void)
发货响应头中的重定向地址; -
int getSize(void)
返回响应正文数据字节数; -
WiFiClient& getStream(void)
WiFiClient* getStreamPtr(void)
返回响应正文数据流; -
int writeToStream(Stream* stream)
将响应正文数据流想入其它流对象;
如果成功则返回写入字节数,否则返回错误代码; -
String getString(void)
返回响应正文数据; -
static String errorToString(int error)
获取错误代码并且以字符串形式返回; -
void end(void)
结束当前连接;
状态码与错误代码
HTTP通讯中的状态码通常就是三位数值,比如2xx表示成功,3xx表示重定向,4xx表示客户端请求的数据不存在或是有错误,5xx表示服务器存在异常,在 HTTPClient.h
中对此还进一步进行的定义,比如 HTTP_CODE_OK = 200
、 HTTP_CODE_NOT_FOUND = 404
等。
HTTPClient库的错误代码也定义在 HTTPClient.h
中,数值均为负值,比如 HTTPC_ERROR_CONNECTION_LOST = -5
、 HTTPC_ERROR_READ_TIMEOUT = -11
。
总结
如果有HTTP协议相关基础的话,HTTPClient库本身使用并不复杂,更多内容可以参考下面链接:
https://github.com/espressif/arduino-esp32/tree/master/libraries/HTTPClient