Espruino:Примеры/Обработка POST-данных, присланных через HTML-форму
Обработка POST-данных, присланных через HTML-форму[1]
В этом руководстве рассказывается о простом способе отправки данных в URL веб-страницы. Но этот способ может оказаться ненадёжным, если что-нибудь, находящееся между вашим браузером и Espruino, решит закэшировать отправленные данные.
Для решения этой проблемы в протоколе HTTP есть запросы типа POST, которые отличаются от обычных запросов GET тем, что всегда сообщают о необходимости отправить данные обратно на сервер. Код ниже – это пример использования запроса POST для включения и выключения двух светодиодов при помощи HTML-формы.
Код ниже состоит из 5 главных частей:
- onInit() – запускается в самом начале и инициализирует WiFi.
- onConnected() – запускается при создании WiFi-соединения. Печатает IP-адрес и запускает веб-сервер.
- onPageRequest() – обрабатывает запрос веб-страницы или отправляет ошибку «404 Page Not Found» (в ситуации с неизвестной URL-ссылкой).
- handlePOST() – вызывается, когда Espruino получает данные POST-запроса. Она принимает данные, разделяет и расшифровывает их, (исходя из присланных данных) включает/выключает светодиоды, а затем вызывает функцию обратного вызова
- sendPage() – создаёт веб-страницу с HTML-формой
Функция handlePOST() может обработать все данные, присланные в POST-запросе, уже после закрытия соединения (обычно так и делается). Но нам нужно отправить обратно веб-страницу, показывающую текущее состояние двух управляемых нами светодиодов. Это значит, что при получении POST-запроса мы должны повременить с отправкой веб-страницы (с помощью sendPage()), пока handlePOST() не примет и не обработает все данные, заданные в HTML-форме (индикатором этого служит событие end в HTTP-запросе).
Вам понадобятся
Устройство, которое можно подключить к интернету – вроде связки Espruino Pico + ESP8266 или Espruino WiFi (без «компаньона»).
Код
Просто скопируйте и вставьте код ниже в Web IDE, затем укажите в переменных WIFI_NAME и WIFI_KEY значения, соответствующие вашей WiFi-сети, и удалите ненужную функцию onInit(). То есть, если вы используете Espruino Pico и ESP8266, удалите onInit() для Espruino WiFi, и наоборот.
Если вы используете какое-то другое устройство, загляните в его документацию и создайте собственную функцию onInit().
Наконец, кликните в Web IDE на кнопку загрузки кода.
var WIFI_NAME = "";
var WIFI_KEY = "";
var wifi;
// Данные, которые были присланы через POST-запрос в прошлый раз:
var postData = {};
// Эта функция для создания веб-страницы:
function sendPage(res) {
// Мы используем здесь шаблонные литералы ES6,
// чтобы код было максимально удобно читать:
var d = `
<html>
<body>
<form action="#" method="post">
<label for="mytext">Some text to send:</label>
<input type="text" id="mytext" name="mytext" value="Testing"/><br/>
<label for="led1">LED1 (red):</label>
<input type="checkbox" id="led1" name="led1" value="1" ${postData.led1?"checked":""}><br/>
<label for="led2">LED2 (green):</label>
<input type="checkbox" id="led2" name="led2" value="1" ${postData.led2?"checked":""}><br/>
<button>Submit</button>
</form>
</body>
</html>`;
res.writeHead(200, {'Content-Type': 'text/html', 'Content-Length':d.length});
res.end(d);
}
// Эта функция обрабатывает сам HTTP-запрос
// и генерирует веб-страницу или страницу с ошибкой «404»:
function onPageRequest(req, res) {
var a = url.parse(req.url, true);
if (a.pathname=="/") {
// Обрабатываем '/' (корневую) страницу...
// Если получили POST-запрос, обрабатываем присланные данные:
if (req.method=="POST" &&
req.headers["Content-Type"]=="application/x-www-form-urlencoded")
handlePOST(req, function() { sendPage(res); });
else
sendPage(res);
} else {
// Страница не найдена – возвращаем ошибку «404»:
res.writeHead(404, {'Content-Type': 'text/plain'});
res.end("404: Page "+a.pathname+" not found");
}
}
// Эта функция обрабатывает все данные, присланные в POST-запросе:
function handlePOST(req, callback) {
var data = "";
req.on('data', function(d) { data += d; });
req.on('end', function() {
// Получили все данные от клиента,
// так что начинаем обрабатывать данные, зашифрованные в URL.
// При использовании «close» HTTP-запрос будет закрыт,
// и мы не сможем отправить страницу с результатом.
postData = {};
data.split("&").forEach(function(el) {
var els = el.split("=");
postData[els[0]] = decodeURIComponent(els[1]);
});
// Наконец, наши данные в «postData»:
console.log(postData);
// Записываем данные из «postData»:
console.log("Мы отправили текст ", postData.mytext);
digitalWrite(LED1, postData.led1);
digitalWrite(LED2, postData.led2);
// Запускаем функцию обратного вызова
// (чтобы отправить HTML-результат):
callback();
});
}
// Эта функция вызывается при создании интернет-соединения:
function onConnected() {
console.log("Подключено!");
wifi.getIP(function(err, ip) {
console.log("Подключились к http://"+ip.ip);
require("http").createServer(onPageRequest).listen(80);
});
}
// Инициализация (ТОЛЬКО для Espruino WiFi):
function onInit() {
wifi = require("EspruinoWiFi");
wifi.connect(WIFI_NAME, { password : WIFI_KEY }, function(err) {
if (err) {
console.log("Ошибка подключения: "+err);
return;
}
onConnected();
});
}
// Инициализация (ТОЛЬКО для Espruino Pico + ESP8266)
function onInit() {
Serial1.setup(115200, { tx: B6, rx : B7 });
wifi = require("ESP8266WiFi_0v25").connect(Serial1, function(err) {
if (err) throw err;
console.log("Подключаемся по WiFi");
wifi.connect(WIFI_NAME, WIFI_KEY, function(err) {
if (err) {
console.log("Ошибка подключения: "+err);
return;
}
onConnected();
});
});
}
// Закройте комментариями эту строчку,
// если планируете сохранить свой код:
onInit();
Спустя несколько секунд после загрузки вы должны увидеть строчку вроде:
Подключились к http://192.168.1.85
Если кликнуть на этот URL или скопировать и вставить его в браузер, у вас должно получиться примерно следующее:
Теперь попробуйте поставить какую-нибудь из галочек и кликнуть на Submit – это включит светодиод (или светодиоды), соответствующий выбранной галочке.
Более подробную информацию о самом коде смотрите в комментариях к нему, а о формах – в этой отличной статье на MDN.
См.также
Внешние ссылки