使用Arduino开发ESP32(20):使用HTTPClient访问HTTP服务器

目的

很多时候我们需要ESP32去访问外网的服务器,HTTP服务器是最常见的服务器,在这个时候就需要ESP32作为HTTPClient使用,这篇文章将对相关内容做个说明。

基础说明

HTTPClient从原理角度来说使用并不复杂,主要步骤如下:

  • 引用库 #include <HTTPClient.h>
  • 连上网;
  • 声明 HTTPClient 对象;
  • 使用 begin() 方法准备要访问的 url
  • 填写请求头内容(如果需要的话);
  • 发起 GETPOST 等请求,并接收返回的状态码;
  • 根据需求读取响应头或响应正文内容;
  • 使用 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 = 200HTTP_CODE_NOT_FOUND = 404 等。

HTTPClient库的错误代码也定义在 HTTPClient.h 中,数值均为负值,比如 HTTPC_ERROR_CONNECTION_LOST = -5HTTPC_ERROR_READ_TIMEOUT = -11

总结

如果有HTTP协议相关基础的话,HTTPClient库本身使用并不复杂,更多内容可以参考下面链接:
https://github.com/espressif/arduino-esp32/tree/master/libraries/HTTPClient

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Naisu Xu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值