Продолжаем цикл статей о веб-фреймворке 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, что наглядно показано на скриншоте.
На этом мы завершаем рассказ о методах передачи данных. Более подробно работа с формами будет рассмотрена в следующих статьях.


