Продолжаем цикл статей о веб-фреймворке Vibe.d. В прошлых статьях мы научились создавать простые шаблоны для статичного веб-сайта, а также добавлять в них D-код, в том числе исполняемый динамически. Но до сих пор наш учебный сайт умеет только давать информацию пользователю, а вот принять не способен. Сегодня мы это поправим, научившись основам работы с веб-формами.
Vibe.d имеет все «стандартные» возможности для работы с формами. В нём реализованы различные методы передачи данных; отслеживание типов передаваемой информации; всевозможные элементы форм: поля ввода, списки, кнопки и т.д.; он способен принимать файлы на сервер, считывать присланные заголовки (headers) и многое другое. В этой статье мы расскажем о методах передачи данных.
В браузерах, как правило, реализовано два метода: GET и POST. Основное различие их состоит в способе передачи данных веб-формы обрабатывающему скрипту, а именно:
- метод GET отправляет скрипту всю собранную информацию формы как часть URL;
- метод POST передает данные таким образом, что пользователь сайта не видит передаваемые скрипту данные.
Оба метода успешно передают необходимую информацию из веб-формы скрипту, поэтому при выборе того или иного метода, который будет наиболее подходить сайту, нужно учитывать следующие факторы:
- принцип работы метода GET ограничивает объём передаваемой скрипту информации;
- так как метод GET отправляет скрипту всю собранную информацию формы как часть URL (то есть в открытом виде), то это может пагубно повлиять на безопасность сайта;
- страницу, сгенерированную методом GET, можно пометить закладкой (адрес страницы будет всегда уникальный), а страницу, сгенерированную метод POST нельзя (адрес страницы остается неизменным, так как данные в URL не подставляются);
- используя метод GET можно передавать данные не через веб-форму, а через URL страницы, введя необходимые значения через знак &;
- метод POST в отличие от метода GET позволяет передавать запросу файлы;
- при использовании метода GET существует риск того, что поисковый робот может выполнить тот или иной открытый запрос. [1]
Сделаем две простые формы в файле index.dt. Одна с методом POST, другая с GET:
- import std.string : toUpper; - string title = "Работа с формами в Vibe.d"; doctype html head title = title body h1 Форма с методом POST form(method='post', action='created') p label Заголовок input(name='form_topic', type='text', required) p label Содержимое textarea(name='form_content') p button(type='reset') Очистить button(type='submit') Сохранить h1 Форма с методом GET form(method='get', action='created') p label Заголовок input(name='form_topic', type='text', required) p label Содержимое textarea(name='form_content') p button(type='reset') Очистить button(type='submit') Сохранить
Также создадим шаблон created.dt, который будет отображать переданную через форму информацию:
- import std.array: empty; doctype html head title Новая запись: #{topic} body h1 #{topic}. - if (content.empty) p Вы ничего не передали. - else p #{content}.
Напоминаем, что все шаблоны (*.dt) следует держать в директории /views/.
Теперь изменим наш app.d так, чтобы он мог обрабатывать присылаемые формами данные:
import vibe.d; shared static this() { auto router = new URLRouter; router.get("/", staticTemplate!"index.dt"); // получить данные методом POST router.post("/created", &createNote); // получить данные методом GET router.get("/created", &createNote); auto settings = new HTTPServerSettings; settings.port = 8080; settings.bindAddresses = ["::1", "127.0.0.1"]; listenHTTP(settings, router); logInfo("Please open http://127.0.0.1:8080/ in your browser."); } // метод создания записи void createNote(HTTPServerRequest req, HTTPServerResponse res) { // если форма не передана, то возвратим пустоту (предосторожность) if (req.method != HTTPMethod.POST && req.method != HTTPMethod.GET) return; // узнаем метод, которым переданы данные // если formdata = POST, то используем req.form // иначе (т.е. для GET) используем req.query auto formdata = (req.method == HTTPMethod.POST) ? &req.form : &req.query; string topic = formdata.get("form_topic"); // получаем заголовок формы string content = formdata.get("form_content"); // получаем содержимое формы render!("created.dt", topic, content)(res); // отображаем шаблон записи с полученными данными }
Компилируем и запускаем. Заполняем поля первой формы и жмем кнопку «Сохранить»:
Открывается страничка с нашей записью:
Если заполнить вторую форму, которая передает данные GET методом, то получится почти то же самое:
Различие, как уже было сказано, в том, что метод GET передает данные через URL, что наглядно показано на скриншоте.
На этом мы завершаем рассказ о методах передачи данных. Более подробно работа с формами будет рассмотрена в следующих статьях.