Веб-сервер на ESP8266: получение параметров запроса

Добавлено 10 мая 2021 в 21:48

Цель данной статьи – объяснить, как получить доступ к параметрам, передаваемым в HTTP GET-запросах, отправленных на веб-сервер, развернутый на ESP8266.

Введение

Параметры HTTP GET-запроса появляются в конце пути URL и позволяют передавать дополнительную информацию. Эти параметры составляют строку запроса и отделяются от пути в URL-адресе знаком вопроса ('?').

Каждый параметр запроса указывается в формате "ИмяПараметра=ЗначениеПараметра". Если необходимо передать несколько параметров, их следует разделить амперсандами ('&').

Итак, ниже показан пример URL-адреса с параметрами GET-запроса.

http://website.com/path?parameter1=value1&parameter2=value2

Таким образом, GET-запрос можно использовать для передачи на ESP8266 дополнительной информации, которая на веб-сервере может быть прочитана функциями обработки.

Обратите внимание, что в данной статье термины параметр и аргумент запроса используются в одинаковом значении при обращении к значениям, переданным в URL-адресе.

Если еще вы не знакомы с технологией создания веб-сервера на базе Wi-Fi модуля ESP8266, то сначала просмотрите следующие статьи:

Код

Инициализирующая часть кода почти такая же, какую мы рассматривали в предыдущем посте о настройке HTTP-сервера на ESP8266, поэтому здесь будет представлено только краткое резюме. Мы начинаем с подключения к сети Wi-Fi, а затем определяем, по каким URL-адресам наш веб-сервер будет прослушивать входящие HTTP-запросы. В данном примере ESP8266 работает в режиме Wi-Fi Station (STA).

Для каждого URL-адреса мы указываем функцию обработки, которая будет выполняться при запросе по этому URL-адресу.

В этом конкретном случае мы определим 2 URL-адреса. В первом мы сможем получить любое количество параметров запроса с любыми именами и значениями. Затем наша функция обработки сформирует и вернет сообщение с ними. Имя этого URL-адреса будет genericArgs. Обратите внимание на заглавную букву 'A', которую необходимо учитывать при доступе к URL-адресу, поскольку он будет чувствителен к регистру.

Другой URL-адрес также получает любое количество параметров запроса, но будет искать конкретное имя параметра и выводить сообщение «not found» (не найдено), если его нет.

Мы проанализируем функции обработки этих двух URL-адресов позже. Сейчас приведем полный код для инициализации веб-сервера.

#include <ESP8266WiFi.h> 
#include <ESP8266WebServer.h>

/* Установите здесь свои SSID и пароль */
const char* ssid = "YourNetworkName";  // SSID
const char* password = "YourPassword"; // пароль

// Объект веб-сервера. Будет прослушивать порт 80 (по умолчанию для HTTP)
ESP8266WebServer server(80);   

void setup() 
{
  Serial.begin(115200);
  delay(100);

  Serial.println("Connecting to ");
  Serial.println(ssid);

  // подключиться к вашей локальной wi-fi сети
  WiFi.begin(ssid, password);

  // проверить, подключился ли wi-fi модуль к wi-fi сети
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(1000);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected..!");
  Serial.print("Got IP: ");  
  Serial.println(WiFi.localIP());

  server.on("/genericArgs", handleGenericArgs);  // привязать функцию обработчика к URL-пути
  server.on("/specificArgs", handleSpecificArg); // привязать функцию обработчика к URL-пути

  server.begin();                                // запуск сервера
  Serial.println("HTTP server started");  

}

void loop() 
{
  server.handleClient();    // обработка входящих запросов

}

Теперь рассмотрим код двух функций-обработчиков для определенных URL-адресов. И снова библиотека ESP8266WebServer предоставляет нам простые в использовании функции для доступа к параметрам запроса, передаваемым в HTTP-запросах.

Проверка всех параметров запроса

В функции-обработчике, которая обрабатывает общие параметры запроса, мы сначала проверим, сколько их было передано. Для этого мы вызываем метод args для объекта server. Этот метод вернет количество параметров запроса, переданных в HTTP-запросе, который инициировал выполнение функции обработчика.

String message = "Number of args received:";
message += server.args();

Затем мы выполним итерацию через каждый параметр и напечатаем имя аргумента и его значение.

Для определения имени параметра мы будем использовать метод argName объекта сервера, который принимает в качестве параметра целое число (номер параметра) и возвращает имя аргумента в этой позиции. Отсчет параметров начинается с нуля.

Для определения значения параметра мы будем использовать метод arg, который также принимает в качестве параметра целое число (номер параметра) и возвращает значение этого параметра.

Итак, мы создаем цикл for от 0 до количества аргументов минус один (отсчет аргументов начинается с нуля) и добавляем в нашу строку ответа имя и значение параметра запроса.

for (int i = 0; i < server.args(); i++) 
{
  message += "Arg nº" + (String)i + " –>";
  message += server.argName(i) + ": ";
  message += server.arg(i) + "\n";
} 

И в конце мы возвращаем сообщение, созданное с помощью метода send объекта сервера, как мы это делали ранее, только в этом случае, для примера, мы возвращаем простой текст. Мы возвращаем его как "text/plan" и с HTTP-кодом OK.

server.send(200, "text/plain", message);

Полный код функции обработчика показан ниже.

void handleGenericArgs() //обработчик
{
  String message = "Number of args received:";
  message += server.args();      // получить количество параметров
  message += "\n";               // переход на новую строку

  for (int i = 0; i < server.args(); i++) 
  {
    message += "Arg nº" + (String)i + " –> "; // добавить текущее значение счетчика
    message += server.argName(i) + ": ";      // получить имя параметра
    message += server.arg(i) + "\n";          // получить значение параметра
  } 

  server.send(200, "text/plain", message);    // ответить на HTTP запрос
}

Поиск конкретного параметра запроса

Теперь рассмотрим функцию, которая ищет конкретное имя параметра и печатает его значение, если оно найдено. В этом случае мы будем искать аргумент с именем "Temperature". Еще раз, мы должны учитывать, что имя аргумента чувствительно к регистру, и поэтому, если мы передадим в качестве параметра "temperature", он не будет найден.

Мы снова вызываем упомянутый ранее метод arg, но на этот раз он получит в качестве входного аргумента строку, содержащую имя параметра запроса, который мы хотим найти. Если параметр не найден, функция вернет пустую строку (соответствующую ""). Если параметр найден, функция вернет значение параметра запроса.

Итак, в нашем коде мы вызываем метод arg, ищем возвращаемое значение и формируем возвращаемую строку, чтобы включить ее в ответ на запрос. И в конце возвращаем HTTP-ответ с помощью метода send, как мы это делали в предыдущей функции обработчика. Код функции показан ниже.

void handleSpecificArg() 
{ 
  String message = "";

  if (server.arg("Temperature")== "") 
  { // параметр не найден
    message = "Temperature Argument not found";
  }
  else
  { // параметр найден
    message = "Temperature Argument = ";
    message += server.arg("Temperature");     // получить значение параметра запроса
  }

  server.send(200, "text/plain", message);    // возвращаем HTTP-ответ
}

Конечные результаты

Мы можем протестировать наш HTTP веб-сервер с помощью веб-браузера, такого как Google Chrome. Первый пример, показанный на рисунке 1, показывает, что происходит, когда мы обращаемся к URL-адресу "/genericArgs" без каких-либо параметров запроса.

Поскольку мы не отправляли никаких параметров, выходные данные показывают, что количество полученных аргументов равно нулю.

Рисунок 1 Результат доступа к URL-адресу /genericArgs без параметров запроса
Рисунок 1 – Результат доступа к URL-адресу /genericArgs без параметров запроса

На скриншоте 2 показано, что произойдет, если мы обратимся к тому же URL-адресу, но теперь передадим параметры запроса. В этом случае мы отправляем 3 параметра, которые представляют дату. Как можно видеть, в ответе сервера указано, что было получено 3 аргумента, а затем перечислены имена и значения этих аргументов.

Рисунок 2 Результат доступа к URL-адресу /genericArgs с 3 параметрами запроса
Рисунок 2 – Результат доступа к URL-адресу /genericArgs с 3 параметрами запроса

На скрнишоте 3 показано, что произойдет, если мы обратимся к URL-адресу /specificArg с параметром запроса, отличающимся от того, что мы ожидаем. В этом случае мы отправили "Luminosity" вместо "Temperature", поэтому в ответе на HTTP-запрос сказано, что аргумент "Temperature" не найден.

Рисунок 3 Результат доступа к URL-адресу /specificArgs с неправильным параметром запроса
Рисунок 3 – Результат доступа к URL-адресу /specificArgs с неправильным параметром запроса

Наконец, как показано на рисунке 4, когда мы запрашиваем этот же URL-адрес, отправляя правильный параметр запроса, наша функция обработчика распознает его и возвращает его значение.

Рисунок 4 Результат доступа к URL-адресу /specificArgs с правильным параметром запроса
Рисунок 4 – Результат доступа к URL-адресу /specificArgs с правильным параметром запроса

Теги

Arduino IDEESP8266EspressifHTTPIoT (интернет вещей)NodeMCUВеб-сервер

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.


  • 2021-09-01radioprog
    желательно заменить в строке кода String message = “Number of args received:”; те кавычки, которые там, на обычные


    Спасибо! Исправил.
    Как-то упустил эту строку.

  • 2021-08-25Alexander Shulga

    Благодарю за проделанную работу. Я обычно ищу инфо на русском, если не нахожу, то на английском. Только желательно заменить в строке кода String message = “Number of args received:”; те кавычки, которые там, на обычные. Иначе код не компилируется. Из статьи-источника: "When directly copying the code from the blog, a stray error may occur when trying to compile it on Arduino. In my case, this occurs because the editor assumes the wrong type of quotes."
    Я хочу , чтобы мои устройства можно было конфигурировать (изменять параметры) самым простым способом- подключившись с помощью телефона. Так как цены Ардуино и ESP8266 не сильно отличаются, вопрос только в логических уровнях, хочу попробовать заменить Ардуино на ESP.