新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > Arduino ESP8266 HTTPClient庫(kù)的使用

Arduino ESP8266 HTTPClient庫(kù)的使用

作者: 時(shí)間:2024-04-16 來(lái)源:linux與嵌入式系統(tǒng) 收藏

1.前言

本文引用地址:http://2s4d.com/article/202404/457687.htm

在前面的文章中,介紹了 WiFi庫(kù) Tcp client的用法,并且用TCP模擬了Http請(qǐng)求。單缺點(diǎn)也很明顯請(qǐng)求頭需要我們自己來(lái)封裝,一不留神就會(huì)出錯(cuò),那么有沒(méi)有一種好的方法來(lái)處理呢?那么是有的,我們可以使用提供的HTTPClient庫(kù),這樣我們就可以方便的來(lái)處理HTTPClient請(qǐng)求。

HTTPClient庫(kù)不屬于WiFi庫(kù)的一部分,所以需要引入#include <ESP8266HTTPClient.h>這個(gè)庫(kù)

2.HTTPClient庫(kù)

總的來(lái)說(shuō)根據(jù)功能來(lái)分的話可以分為兩類(lèi)請(qǐng)求和響應(yīng)。大家也可以下載HTTPclient庫(kù)的源碼進(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請(qǐng)求的相關(guān)函數(shù)
2.1.1 begin封裝請(qǐng)求的URL

bool begin(String url)

自動(dòng)解析url以獲得所有參數(shù),默認(rèn)port是80端口,,返回值為布爾類(lèi)型,可以選讀, 參數(shù)URL可以為以下幾種格式,使用哪種格式按需求決定:

1. http://192.168.1.18/test.html

2. http://user:password@192.168.1.18/test.html

后面兩種是需要驗(yàn)證的user:用戶名, password是密碼;

如果不帶有端口號(hào)的話默認(rèn)是80,不是80的話可以在host后面加上如:192.168.1.14:80;

bool begin(String host, uint16_t port, String uri = "/test.html");

設(shè)置host,port以及URL,特別需要注意的是在設(shè)置host時(shí)不要加http://

2.1.2 setReuse —— 封裝請(qǐng)求頭keep-alive

void setReuse(bool reuse);

設(shè)置connect屬性是否為keep-alive,reuse為true時(shí)設(shè)置為keep-alive;

2.1.3.setUserAgent —— 封裝User-Agent請(qǐng)求頭

void setUserAgent(const String& userAgent);

封裝User-Agent 的內(nèi)容如: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:的內(nèi)容傳給userAgent即可;

2.1.4. setAuthorization

Authorization 是采用 basic auth 授權(quán)方式驗(yàn)證客戶端請(qǐng)求,Authorization 請(qǐng)求頭對(duì)應(yīng)的值是 (basic base64編碼) 忽略括號(hào),其中 base64編碼是將 用戶名:密碼 這種格式進(jìn)行處理生成**的,并且自動(dòng)在 header 中添加 Authorization。

1.void setAuthorization(const char * user, const char * password);

2.void setAuthorization(const char * auth);

封裝標(biāo)準(zhǔn)請(qǐng)求頭Authorization(訪問(wèn)權(quán)限認(rèn)證請(qǐng)求頭信息)

2.1.5 addHeader

void addHeader(const String& name, const String& value, bool first = false, bool replace = true);

封裝自定義請(qǐng)求頭,name 自定義請(qǐng)求頭的名字,value 自定義請(qǐng)求頭的參數(shù)值,first 是否要把當(dāng)前請(qǐng)求頭放在請(qǐng)求頭的最前面,replace 是否需要替換之前已經(jīng)存在該請(qǐng)求頭的參數(shù)值,默認(rèn)就是覆蓋舊值。在使用時(shí)需要注意的是自定義請(qǐng)求頭,請(qǐng)求頭不能為 Connection、User-Agent、Host、Authorization。

void HTTPClient::addHeader(const String& name, const String& value, bool first, bool replace)

{

// 過(guò)濾請(qǐng)求頭

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 請(qǐng)求

int GET();

發(fā)送一個(gè)get請(qǐng)求并返回http 狀態(tài)碼

2.1.7 POST 請(qǐng)求

該方法有兩種形式:

1.int POST(uint8_t * payload, size_t size);

2.int POST(String payload);

第一種是義字符數(shù)組的形式發(fā)送請(qǐng)求,需要傳遞數(shù)組長(zhǎng)度,第二種是以字符串形式的發(fā)送,兩者返回的都是HTTP的狀態(tài)碼。

2.1.8 PUT 請(qǐng)求

該方法也有兩種形式:

int PUT(uint8_t * payload, size_t size);

int PUT(String payload);

參數(shù)和返回值同上。

2.1.8 PATCH 請(qǐng)求

int PATCH(uint8_t * payload, size_t size);

int PATCH(String payload);

參數(shù)和返回值同上。

2.1.9 sendRequest 發(fā)送請(qǐng)求

GET、POST、PUT、PATCH最終都會(huì)調(diào)用sendRequest方法。三種形式如下:

int sendRequest(const char * type, String payload);

type:請(qǐng)求類(lèi)型POST、GET、PUT……….

payload:請(qǐng)求要攜帶的數(shù)據(jù)

int sendRequest(const char * type, uint8_t * payload = NULL, size_t size = 0);

type:請(qǐng)求類(lèi)型POST、GET、PUT……….

payload:請(qǐng)求要攜帶的數(shù)據(jù)

size:數(shù)據(jù)長(zhǎng)度

int sendRequest(const char * type, Stream * stream, size_t size = 0);

type:請(qǐng)求類(lèi)型POST、GET、PUT……….

payload:請(qǐng)求要攜帶的數(shù)據(jù)流

size:數(shù)據(jù)流長(zhǎng)度

2.1.10 setTimeout

void setTimeout(uint16_t timeout);

設(shè)置請(qǐng)求超時(shí)時(shí)間,時(shí)間單位為ms,如果不設(shè)置默認(rèn)為5000ms.

2.1.11 useHTTP10

void useHTTP10(bool usehttp10 = true);

設(shè)置HTTP協(xié)議的版本,是1.0的話為true,否則為false

2.1.12 end

void end(void);

結(jié)束請(qǐng)求,需要注意的是在keep-alive情況下不會(huì)斷開(kāi)連接,只會(huì)清除接收緩沖區(qū);

2.2 http響應(yīng)方法

2.2.1 collectHeaders

void collectHeaders(const char* headerKeys[], const size_t headerKeysCount);

設(shè)置需要收集的響應(yīng)頭,

headerKeys[]:響應(yīng)頭的名字

headerKeysCount:響應(yīng)頭的個(gè)數(shù)

2.2.2 header(name)

String header(const char* name);

獲取具體響應(yīng)頭參數(shù)值,name:響應(yīng)頭的名字,返回參數(shù)值。

2.2.3 header(index)

String header(size_t i);

獲取第i個(gè)響應(yīng)頭參數(shù)值,參數(shù)響應(yīng)頭的索引號(hào),返回索引號(hào)對(duì)應(yīng)的參數(shù)值。

2.2.4 headerName(index)

函數(shù)說(shuō)明:

String headerName(size_t i);

獲取第i個(gè)響應(yīng)頭名字,參數(shù)為響應(yīng)頭索引值,返回響應(yīng)頭名字。

注意點(diǎn):

如果沒(méi)有調(diào)用collectHeaders(),那就會(huì)默認(rèn)返回空字符串;

2.2.5 headers()

int headers();

獲取收集響應(yīng)頭個(gè)數(shù)

2.2.6 hasHeader(name)

bool hasHeader(const char* name);

判斷某一個(gè)響應(yīng)頭是否存在,name:響應(yīng)頭名字,存在返回true,否則返回false.

2.2.7 handleHeaderResponse

int handleHeaderResponse()

讀取從服務(wù)器返回的響應(yīng)頭數(shù)據(jù),返回http的狀態(tài)碼。

2.2.8 getString

String getString(void);

獲取響應(yīng)數(shù)據(jù)

2.2.9 getStream

WiFiClient& getStream(void);

獲取響應(yīng)數(shù)據(jù)的流

2.2.10 getStreamPtr

WiFiClient* getStreamPtr(void);

獲取響應(yīng)數(shù)據(jù)的流

2.2.11 writeToStream

int writeToStream(Stream* stream);

獲取響應(yīng)數(shù)據(jù)的流,并寫(xiě)到其他流對(duì)象。Stream:流對(duì)象,返回寫(xiě)成功的字節(jié)數(shù)。

在講解該函數(shù)之前,先簡(jiǎn)單介紹一下 分塊編碼(Transfer-Encoding: chunked):Transfer-Encoding,是一個(gè) HTTP 頭部字段(響應(yīng)頭域),字面意思是「?jìng)鬏斁幋a」。最新的 HTTP 規(guī)范里,只定義了一種編碼傳輸:分塊編碼(chunked)。

分塊傳輸編碼(Chunked transfer encoding)是超文本傳輸協(xié)議(HTTP)中的一種數(shù)據(jù)傳輸機(jī)制,允許HTTP由網(wǎng)頁(yè)服務(wù)器發(fā)送給客戶端的數(shù)據(jù)可以分成多個(gè)部分。分塊傳輸編碼只在HTTP協(xié)議1.1版本(HTTP/1.1)中提供。

數(shù)據(jù)分解成一系列數(shù)據(jù)塊,并以一個(gè)或多個(gè)塊發(fā)送,這樣服務(wù)器可以發(fā)送數(shù)據(jù)而不需要預(yù)先知道發(fā)送內(nèi)容的總大小。

具體方法

在頭部加入 Transfer-Encoding: chunked 之后,就代表這個(gè)報(bào)文采用了分塊編碼。這時(shí),報(bào)文中的實(shí)體需要改為用一系列分塊來(lái)傳輸。

每個(gè)分塊包含十六進(jìn)制的長(zhǎng)度值和數(shù)據(jù),長(zhǎng)度值獨(dú)占一行,長(zhǎng)度不包括它結(jié)尾的 CRLF(rn),也不包括分塊數(shù)據(jù)結(jié)尾的 CRLF。

最后一個(gè)分塊長(zhǎng)度值必須為 0,對(duì)應(yīng)的分塊數(shù)據(jù)沒(méi)有內(nèi)容,表示實(shí)體結(jié)束。

2.2.12 getSize

int getSize(void);

獲取響應(yīng)數(shù)據(jù)字節(jié)數(shù),返回響應(yīng)數(shù)據(jù)字節(jié)數(shù)。

對(duì)于有 Content-Length,會(huì)把Content-Length賦值給size;

如果存在 Transfer-Encoding:chunked,size是通過(guò)計(jì)算響應(yīng)內(nèi)存長(zhǎng)度來(lái)獲得;

2.2.13 errorToString

static String errorToString(int error);

獲取請(qǐng)求失敗響應(yīng)信息,根據(jù)錯(cuò)誤碼error返回具體錯(cuò)誤信息,error 錯(cuò)誤碼

返回的是錯(cuò)誤碼對(duì)應(yīng)的錯(cuò)誤信息。



關(guān)鍵詞: ESP8266

評(píng)論


相關(guān)推薦

技術(shù)專(zhuān)區(qū)

關(guān)閉