Arduino ESP8266 HTTPClient庫的使用
1.前言
本文引用地址:http://dyxdggzs.com/article/202404/457687.htm在前面的文章中,介紹了ESP8266 WiFi庫 Tcp client的用法,并且用TCP模擬了Http請求。單缺點(diǎn)也很明顯請求頭需要我們自己來(lái)封裝,一不留神就會(huì )出錯,那么有沒(méi)有一種好的方法來(lái)處理呢?那么是有的,我們可以使用提供的HTTPClient庫,這樣我們就可以方便的來(lái)處理HTTPClient請求。
ESP8266 HTTPClient庫不屬于ESP8266WiFi庫的一部分,所以需要引入#include <ESP8266HTTPClient.h>這個(gè)庫
2.HTTPClient庫
總的來(lái)說(shuō)根據功能來(lái)分的話(huà)可以分為兩類(lèi)請求和響應。大家也可以下載HTTPclient庫的源碼進(jìn)行分析研究。
POST / HTTP1.1
Host:www.wrox.com
User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
Content-Type:application/x-www-form-urlencoded
Content-Length:40
Connection: Keep-Alive
2.1請求的相關(guān)函數
2.1.1 begin封裝請求的URL
bool begin(String url)
自動(dòng)解析url以獲得所有參數,默認port是80端口,,返回值為布爾類(lèi)型,可以選讀, 參數URL可以為以下幾種格式,使用哪種格式按需求決定:
1. http://192.168.1.18/test.html
2. http://user:password@192.168.1.18/test.html
后面兩種是需要驗證的user:用戶(hù)名, password是密碼;
如果不帶有端口號的話(huà)默認是80,不是80的話(huà)可以在host后面加上如:192.168.1.14:80;
bool begin(String host, uint16_t port, String uri = "/test.html");
設置host,port以及URL,特別需要注意的是在設置host時(shí)不要加http://
2.1.2 setReuse —— 封裝請求頭keep-alive
void setReuse(bool reuse);
設置connect屬性是否為keep-alive,reuse為true時(shí)設置為keep-alive;
2.1.3.setUserAgent —— 封裝User-Agent請求頭
void setUserAgent(const String& userAgent);
封裝User-Agent 的內容如:User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)將User-Agent:的內容傳給userAgent即可;
2.1.4. setAuthorization
Authorization 是采用 basic auth 授權方式驗證客戶(hù)端請求,Authorization 請求頭對應的值是 (basic base64編碼) 忽略括號,其中 base64編碼是將 用戶(hù)名:密碼 這種格式進(jìn)行處理生成**的,并且自動(dòng)在 header 中添加 Authorization。
1.void setAuthorization(const char * user, const char * password);
2.void setAuthorization(const char * auth);
封裝標準請求頭Authorization(訪(fǎng)問(wèn)權限認證請求頭信息)
2.1.5 addHeader
void addHeader(const String& name, const String& value, bool first = false, bool replace = true);
封裝自定義請求頭,name 自定義請求頭的名字,value 自定義請求頭的參數值,first 是否要把當前請求頭放在請求頭的最前面,replace 是否需要替換之前已經(jīng)存在該請求頭的參數值,默認就是覆蓋舊值。在使用時(shí)需要注意的是自定義請求頭,請求頭不能為 Connection、User-Agent、Host、Authorization。
void HTTPClient::addHeader(const String& name, const String& value, bool first, bool replace)
{
// 過(guò)濾請求頭
if(!name.equalsIgnoreCase(F("Connection")) &&
!name.equalsIgnoreCase(F("User-Agent")) &&
!name.equalsIgnoreCase(F("Host")) &&
!(name.equalsIgnoreCase(F("Authorization")) && _base64Authorization.length())){
String headerLine = name;
headerLine += ": ";
if (replace) {
int headerStart = _headers.indexOf(headerLine);
if (headerStart != -1) {
int headerEnd = _headers.indexOf('n', headerStart);
_headers = _headers.substring(0, headerStart) + _headers.substring(headerEnd + 1);
}
}
headerLine += value;
headerLine += "rn";
if(first) {
_headers = headerLine + _headers;
} else {
_headers += headerLine;
}
}
}
2.1.6 GET 請求
int GET();
發(fā)送一個(gè)get請求并返回http 狀態(tài)碼
2.1.7 POST 請求
該方法有兩種形式:
1.int POST(uint8_t * payload, size_t size);
2.int POST(String payload);
第一種是義字符數組的形式發(fā)送請求,需要傳遞數組長(cháng)度,第二種是以字符串形式的發(fā)送,兩者返回的都是HTTP的狀態(tài)碼。
2.1.8 PUT 請求
該方法也有兩種形式:
int PUT(uint8_t * payload, size_t size);
int PUT(String payload);
參數和返回值同上。
2.1.8 PATCH 請求
int PATCH(uint8_t * payload, size_t size);
int PATCH(String payload);
參數和返回值同上。
2.1.9 sendRequest 發(fā)送請求
GET、POST、PUT、PATCH最終都會(huì )調用sendRequest方法。三種形式如下:
int sendRequest(const char * type, String payload);
type:請求類(lèi)型POST、GET、PUT……….
payload:請求要攜帶的數據
int sendRequest(const char * type, uint8_t * payload = NULL, size_t size = 0);
type:請求類(lèi)型POST、GET、PUT……….
payload:請求要攜帶的數據
size:數據長(cháng)度
int sendRequest(const char * type, Stream * stream, size_t size = 0);
type:請求類(lèi)型POST、GET、PUT……….
payload:請求要攜帶的數據流
size:數據流長(cháng)度
2.1.10 setTimeout
void setTimeout(uint16_t timeout);
設置請求超時(shí)時(shí)間,時(shí)間單位為ms,如果不設置默認為5000ms.
2.1.11 useHTTP10
void useHTTP10(bool usehttp10 = true);
設置HTTP協(xié)議的版本,是1.0的話(huà)為true,否則為false
2.1.12 end
void end(void);
結束請求,需要注意的是在keep-alive情況下不會(huì )斷開(kāi)連接,只會(huì )清除接收緩沖區;
2.2 http響應方法
2.2.1 collectHeaders
void collectHeaders(const char* headerKeys[], const size_t headerKeysCount);
設置需要收集的響應頭,
headerKeys[]:響應頭的名字
headerKeysCount:響應頭的個(gè)數
2.2.2 header(name)
String header(const char* name);
獲取具體響應頭參數值,name:響應頭的名字,返回參數值。
2.2.3 header(index)
String header(size_t i);
獲取第i個(gè)響應頭參數值,參數響應頭的索引號,返回索引號對應的參數值。
2.2.4 headerName(index)
函數說(shuō)明:
String headerName(size_t i);
獲取第i個(gè)響應頭名字,參數為響應頭索引值,返回響應頭名字。
注意點(diǎn):
如果沒(méi)有調用collectHeaders(),那就會(huì )默認返回空字符串;
2.2.5 headers()
int headers();
獲取收集響應頭個(gè)數
2.2.6 hasHeader(name)
bool hasHeader(const char* name);
判斷某一個(gè)響應頭是否存在,name:響應頭名字,存在返回true,否則返回false.
2.2.7 handleHeaderResponse
int handleHeaderResponse()
讀取從服務(wù)器返回的響應頭數據,返回http的狀態(tài)碼。
2.2.8 getString
String getString(void);
獲取響應數據
2.2.9 getStream
WiFiClient& getStream(void);
獲取響應數據的流
2.2.10 getStreamPtr
WiFiClient* getStreamPtr(void);
獲取響應數據的流
2.2.11 writeToStream
int writeToStream(Stream* stream);
獲取響應數據的流,并寫(xiě)到其他流對象。Stream:流對象,返回寫(xiě)成功的字節數。
在講解該函數之前,先簡(jiǎn)單介紹一下 分塊編碼(Transfer-Encoding: chunked):Transfer-Encoding,是一個(gè) HTTP 頭部字段(響應頭域),字面意思是「傳輸編碼」。最新的 HTTP 規范里,只定義了一種編碼傳輸:分塊編碼(chunked)。
分塊傳輸編碼(Chunked transfer encoding)是超文本傳輸協(xié)議(HTTP)中的一種數據傳輸機制,允許HTTP由網(wǎng)頁(yè)服務(wù)器發(fā)送給客戶(hù)端的數據可以分成多個(gè)部分。分塊傳輸編碼只在HTTP協(xié)議1.1版本(HTTP/1.1)中提供。
數據分解成一系列數據塊,并以一個(gè)或多個(gè)塊發(fā)送,這樣服務(wù)器可以發(fā)送數據而不需要預先知道發(fā)送內容的總大小。
具體方法
在頭部加入 Transfer-Encoding: chunked 之后,就代表這個(gè)報文采用了分塊編碼。這時(shí),報文中的實(shí)體需要改為用一系列分塊來(lái)傳輸。
每個(gè)分塊包含十六進(jìn)制的長(cháng)度值和數據,長(cháng)度值獨占一行,長(cháng)度不包括它結尾的 CRLF(rn),也不包括分塊數據結尾的 CRLF。
最后一個(gè)分塊長(cháng)度值必須為 0,對應的分塊數據沒(méi)有內容,表示實(shí)體結束。
2.2.12 getSize
int getSize(void);
獲取響應數據字節數,返回響應數據字節數。
對于有 Content-Length,會(huì )把Content-Length賦值給size;
如果存在 Transfer-Encoding:chunked,size是通過(guò)計算響應內存長(cháng)度來(lái)獲得;
2.2.13 errorToString
static String errorToString(int error);
獲取請求失敗響應信息,根據錯誤碼error返回具體錯誤信息,error 錯誤碼
返回的是錯誤碼對應的錯誤信息。
評論