我们使用ESP32_Arduino自带库: HTTPClient 
一. 请求相关API函数
 首先,创建一个客户端对象 
 1. 初始化HTTP客户端 http_client.begin() 
 /** 
  * 解析url以获得所有参数,默认port是80端口 
  * @param url String 
  */ 
 bool begin(String url); 
   
 /** 
  * 解析url以获得所有参数,默认port是80端口 
  * @param client : 传入一个网络连接客户端 
  * @param url String 
  */ 
 bool begin(WiFiClient &client, String url); 
   
 /** 
  * 设置host port 以及uri 
  * @param host String(192.168.1.12,不需要带上http://前缀) 
  * @param port uint16_t 
  * @param uri  String 
  */ 
 bool begin(String host, uint16_t port, String uri = "/"); 
   
 /** 
  * 设置host port 以及uri 
  * @param client 传入一个网络连接客户端 
  * @param host String(192.168.1.12,不需要带上http://前缀) 
  * @param port uint16_t 
  * @param uri  String 
  * @param https bool 是否启用https 
  */ 
 bool begin(WiFiClient &client, String host, uint16_t port, String uri = "/", bool https = false); 
   
 /** 
  * 设置host port 以及uri 
  * @param host String(192.168.1.12,不需要带上http://前缀) 
  * @param port uint16_t 
  * @param uri  String 
  * @param CAcert CA证书(https) 
  */ 
 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); 
 2. 设置长连接 http_client.setReuse(true); 
 /** 
  * try to reuse the connection to the server 
  * keep-alive 请求头 
  * @param reuse bool 
  */ 
 void setReuse(bool reuse); // keep-alive 
3. setUserAgent —— 封装标准请求头User-Agent
 /** 
  * set User Agent 
  * User Agent请求头:使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。 
  * @param userAgent const char * 
  */ 
 void setUserAgent(const String& userAgent); 
4. addHeader —— 封装自定义请求头
 函数说明: 
 /** 
  * adds Header to the request 
  * @param name  自定义请求头的名字 
  * @param value 自定义请求头的参数值 
  * @param first 是否要把当前请求头放在请求头的最前面 
  * @param replace 是否需要替换之前已经存在该请求头的参数值,默认就是覆盖旧值 
  */ 
 void addHeader(const String& name, const String& value, bool first = false, bool replace = true); 
5. GET 请求
 函数说明: 
 /** 
  * 发送一个get请求 
  * @return http 状态码 
  */ 
 int GET(); 
6. POST 请求
 函数说明: 
 /** 
  * 发送一个post请求 
  * @param payload uint8_t * 需要提交的数据 
  * @param size size_t 提交的数据的字节数 
  * @return http 状态码 
  */ 
 int POST(uint8_t * payload, size_t size); 
   
 /** 
  * 发送一个post请求 
  * @param payload String 需要提交的数据 
  * @return http 状态码 
  */ 
 int POST(String payload); 
7. PUT 请求
 函数说明: 
 /** 
  * 发送一个PUT请求(博主也没有用过PUT) 
  * @param payload uint8_t * 需要提交的数据 
  * @param size size_t 提交的数据的字节数 
  * @return http 状态码 
  */ 
 int PUT(uint8_t * payload, size_t size); 
 /** 
  * 发送一个PUT请求(博主也没有用过PUT) 
  * @param payload String 需要提交的数据 
  * @return http 状态码 
  */ 
 int PUT(String payload); 
8. PATCH 请求
 函数说明: 
 /** 
  * 发送一个PATCH请求(博主也没有用过PATCH) 
  * @param payload uint8_t * 需要提交的数据 
  * @param size size_t 提交的数据的字节数 
  * @return http 状态码 
  */ 
 int PATCH(uint8_t * payload, size_t size); 
 /** 
  * 发送一个PATCH请求(博主也没有用过PATCH) 
  * @param payload String 需要提交的数据 
  * @return http 状态码 
  */ 
 int PATCH(String payload); 
9. sendRequest 发送请求
 GET、POST、PUT、PATCH最终都会调用sendRequest方法。 
 函数说明: 
 /** 
  * GET、POST、PUT、PATCH最终都会调用sendRequest方法 
  * sendRequest 
  * @param type const char * 请求类型    "GET", "POST", .... 
  * @param payload String  请求携带的数据  data for the message body 
  * @return 
  */ 
 int sendRequest(const char * type, String payload); 
 /** 
  * sendRequest 
  * @param type const char * 请求类型 "GET", "POST", .... 
  * @param payload uint8_t * 请求携带的数据  data for the message body if null not send 
  * @param size size_t  请求携带的数据字节数 size for the message body if 0 not send 
  * @return -1 if no info or > 0 when Content-Length is set by server 
  */ 
 int sendRequest(const char * type, uint8_t * payload = NULL, size_t size = 0); 
 /** 
  * sendRequest 
  * @param type const char *  请求类型 "GET", "POST", .... 
  * @param stream Stream *  请求携带的数据流 data stream for the message body 
  * @param size size_t   数据流大小 size for the message body if 0 not Content-Length is send 
  * @return -1 if no info or > 0 when Content-Length is set by server 
  */ 
 int sendRequest(const char * type, Stream * stream, size_t size = 0); 
 10. setTimeout —— 设置请求超时 
 函数说明: 
 /** 
  * 请求超时时间配置 ms为单位 
  * @param timeout unsigned int  默认500ms 
  */ 
 void setTimeout(uint16_t timeout); 
11. useHTTP10 —— http协议版本
 函数说明: 
 /** 
  * http协议版本 
  * @param usehttp10 true表示用http1.0,默认是false,用http1.1 
  */ 
 void useHTTP10(bool usehttp10 = true); 
12. end —— 结束请求
 函数说明: 
 /** 
  * 结束请求 
  * called after the payload is handled 
  */ 
 void end(void); 
二. 响应相关API
 1. collectHeaders —— 设置需要收集的响应头 
 函数说明: 
 /** 
  * 设置需要收集的响应头(1-n个) 
  * @param headerKeys[] const char *   响应头的名字 
  * @param headerKeysCount const size_t 响应头的个数 
  * 注意点:headerKeys数组元素个数需要大于等于 headerKeysCount 
  */ 
 void collectHeaders(const char* headerKeys[], const size_t headerKeysCount); 
 RequestArgument定义如下: 
 struct RequestArgument { 
     String key;//键值对里面的key 
     String value;//键值对里面的value 
 }; 
 注意点: 
 这个方法收集的headerKeys会在响应数据处理函数中应用到; 
 2. header(name) —— 获取具体响应头参数值 
 函数说明: 
 /** 
  * 获取响应头参数值 
  * @param name   const char *   响应头的名字 
  * @return value of headerkey(name) 
  */ 
 String header(const char* name); 
 如果没有调用collectHeaders(),那就会默认返回空字符串; 
 3. header(index) —— 获取第index个响应头参数值 
 函数说明: 
 /** 
  * 获取第i个响应头参数值 
  * @param i   size_t   响应头索引值 
  * @return value of header index 
  */ 
 String header(size_t i); 
 如果没有调用collectHeaders(),那就会默认返回空字符串; 
 4. headerName(index) —— 获取第i个响应头名字 
 函数说明: 
 /** 
  * 获取第i个响应头名字 
  * @param i   size_t   响应头索引值 
  * @return name of header index 
  */ 
 String headerName(size_t i); 
 如果没有调用collectHeaders(),那就会默认返回空字符串; 
 5. headers() —— 获取收集响应头个数 
 函数说明: 
 /** 
  * 获取收集响应头个数 
  * @return count int 
  */ 
 int headers();                     // get header count 
6. hasHeader(name) —— 判断是否存在某一个响应头
 函数说明: 
 /** 
  * 判断是否存在某一个响应头 
  * @param name   const char*   响应头名字 
  * @return bool 
  */ 
 bool hasHeader(const char* name);  // check if header exists 
7. handleHeaderResponse —— 处理响应头数据
 函数说明: 
 /** 
  * 读取从服务器返回的响应头数据 
  * @return int http状态码 
  */ 
 int handleHeaderResponse() 
8. getString —— 获取响应数据
 函数说明: 
 /** 
  * 把响应数据转成字符串 (可能需要很大内存空间) 
  * @return String 响应数据转成字符串 
  */ 
 String getString(void); 
9. getStream —— 获取响应数据的流
 函数说明: 
 /** 
  * 获取响应数据的流 
  * @return WiFiClient& tcp响应数据的流 
  */ 
 WiFiClient& getStream(void); 
10. getStreamPtr —— 获取响应数据的流
 函数说明: 
 /** 
  * 获取响应数据的流 
  * @return WiFiClient& tcp响应数据的流 
  */ 
 WiFiClient* getStreamPtr(void); 
11. writeToStream —— 获取响应数据的流,并写到其他流对象
 在讲解该函数之前,博主先给读者简单介绍一下 分块编码(Transfer-Encoding: chunked): 
 Transfer-Encoding,是一个 HTTP 头部字段(响应头域),字面意思是「传输编码」。最新的 HTTP 规范里,只定义了一种编码传输:分块编码(chunked)。 
 分块传输编码(Chunked transfer encoding)是超文本传输协议(HTTP)中的一种数据传输机制,允许HTTP由网页服务器发送给客户端的数据可以分成多个部分。分块传输编码只在HTTP协议1.1版本(HTTP/1.1)中提供。 
 数据分解成一系列数据块,并以一个或多个块发送,这样服务器可以发送数据而不需要预先知道发送内容的总大小。 
 具体方法 
 在头部加入 Transfer-Encoding: chunked 之后,就代表这个报文采用了分块编码。这时,报文中的实体需要改为用一系列分块来传输。 
 每个分块包含十六进制的长度值和数据,长度值独占一行,长度不包括它结尾的 CRLF(\r\n),也不包括分块数据结尾的 CRLF。 
 最后一个分块长度值必须为 0,对应的分块数据没有内容,表示实体结束。 
 /** 
  * 把响应数据的流写到其他流对象 
  * @param Stream* 其他流对象 
  * @return int 写成功的字节数 
  */ 
 int writeToStream(Stream* stream); 
12. getSize —— 获取响应数据的字节数
 函数说明: 
 /** 
  * 获取响应数据字节数 
  * @return int 响应数据字节数 
  */ 
 int getSize(void); 
13. errorToString —— 获取请求失败响应信息
 函数说明: 
 /** 
  * 根据错误码error返回具体错误信息 
  * @param error 错误码 
  * @return String 错误码对应的错误信息 
  */ 
 static String errorToString(int error); 
 示例: 
#include <Arduino.h>
#include "WiFi.h"
#include "HTTPClient.h"
 
const char *ssid = "anny";                      //wifi名
const char *password = "******";              //wifi密码
const char *host = "https://api.seniverse.com"; //心知天气APIhost
const char *apiKey = "SZihSaRrzq6LclO30";       //API key 私钥
const char *city = "taian";                     //查询的城市
//示例: https://api.seniverse.com/v3/weather/now.json?key=your_private_key&location=beijing&language=zh-Hans&unit=c
 
WiFiClient wifi_Client;
HTTPClient http_client;
String req;
String rsp;
 
class cityWeather
{
public:
  char cityName[16];
  char weather[32];
  char temp[16];
  char update[32];
};
 
//Wifi连接
void setupWifi()
{
  delay(10);
  Serial.println("connecting WIFI");
  WiFi.begin(ssid, password);
  while (!WiFi.isConnected())
  {
    Serial.print(".");
    delay(500);
  }
  Serial.println("OK");
  Serial.println("Wifi connected");
}
 
void setUpHttpClient()
{
  req = (String)host + "/v3/weather/now.json?key=";
  req += apiKey;
  req += "&location=";
  req += city;
  req += "&language=zh-Hans&unit=c";
  Serial.println(req);
  if (http_client.begin(req))
  {
    Serial.println("HTTPclient setUp done!");
  }
}
 
void setup()
{
  Serial.begin(115200);
  delay(3000);
  setupWifi();
  setUpHttpClient();
}
 
void loop()
{
  int http_code = http_client.GET();
  Serial.println(http_code);
  if (http_code > 0)
  {
    Serial.printf("HTTP get code: %d\n", http_code);
    if (http_code == HTTP_CODE_OK)
    {
      rsp = http_client.getString();
      Serial.println(rsp);
    }
    else
    {
      Serial.printf("fail to get cityWeather,code:%d\n", http_code);
    }
  }
  delay(5000);
}
 ———————————————— 
 链接:https://blog.csdn.net/finedayforu/article/details/108510294