Веб-сервер на ESP8266: получение параметров запроса
Цель данной статьи – объяснить, как получить доступ к параметрам, передаваемым в HTTP GET-запросах, отправленных на веб-сервер, развернутый на ESP8266.
Введение
Параметры HTTP GET-запроса появляются в конце пути URL и позволяют передавать дополнительную информацию. Эти параметры составляют строку запроса и отделяются от пути в URL-адресе знаком вопроса ('?').
Каждый параметр запроса указывается в формате "ИмяПараметра=ЗначениеПараметра". Если необходимо передать несколько параметров, их следует разделить амперсандами ('&').
Итак, ниже показан пример URL-адреса с параметрами GET-запроса.
http://website.com/path?parameter1=value1¶meter2=value2
Таким образом, GET-запрос можно использовать для передачи на ESP8266 дополнительной информации, которая на веб-сервере может быть прочитана функциями обработки.
Обратите внимание, что в данной статье термины параметр и аргумент запроса используются в одинаковом значении при обращении к значениям, переданным в URL-адресе.
Если еще вы не знакомы с технологией создания веб-сервера на базе Wi-Fi модуля ESP8266, то сначала просмотрите следующие статьи:
- Создание простого веб-сервера на ESP8266 NodeMCU в Arduino IDE
- Взаимодействие ESP8266 NodeMCU с датчиками температуры и влажности DHT11 и DHT22 и вывод показаний, используя веб-сервер
- Отображение показаний с нескольких DS18B20 с помощью веб-сервера на ESP8266 NodeMCU
- Создаем простую метеостанцию на ESP8266 с BME280
Код
Инициализирующая часть кода почти такая же, какую мы рассматривали в предыдущем посте о настройке 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" без каких-либо параметров запроса.
Поскольку мы не отправляли никаких параметров, выходные данные показывают, что количество полученных аргументов равно нулю.
На скриншоте 2 показано, что произойдет, если мы обратимся к тому же URL-адресу, но теперь передадим параметры запроса. В этом случае мы отправляем 3 параметра, которые представляют дату. Как можно видеть, в ответе сервера указано, что было получено 3 аргумента, а затем перечислены имена и значения этих аргументов.
На скрнишоте 3 показано, что произойдет, если мы обратимся к URL-адресу /specificArg с параметром запроса, отличающимся от того, что мы ожидаем. В этом случае мы отправили "Luminosity" вместо "Temperature", поэтому в ответе на HTTP-запрос сказано, что аргумент "Temperature" не найден.
Наконец, как показано на рисунке 4, когда мы запрашиваем этот же URL-адрес, отправляя правильный параметр запроса, наша функция обработчика распознает его и возвращает его значение.