Отправка данных из формы post php. Форма отправки данных в PHP (POST, GET)

Чтобы организовать передачу данных на сервер с помощью формы, потребуется реализовать HTML форму, в которую посетители сайта будут вводить свою информацию и PHP код, назначение которого в принятии и обработке полученных данных на сервере.

HTML форма отправки данных

Форма на странице формируется тегами

...
, внутри которых помещаются теги полей для ввода текстовой информации, теги специальных компонентов (например, поле со списком), теги для поля выбора и загрузки файла .

* Для HTML5 так же существует возможность размещать теги полей формы не внутри тегов формы, а в любом месте на странице. При этом для каждого такого поля нужно указывать атрибут "form", чтобы определить с какой формой отправки он должен взаимодействовать.

Итак, простейшая форма отправки может содержать следующий код:


Значение А:
Значение Б:

Элементы формы и их параметры:

action="myform.php" – атрибут "action" определяет, какой php-файл будет обрабатывать отправляемые данные. В этом примере, данные будут отправлены в файл "myform.php", находящийся в той же директории что и страница с формой. Если этот атрибут не указать явно, данные формы будут отправлены по адресу страницы самой формы.

method="post" – параметр method определяет метод передачи данных POST или GET. Более подробно об этом в статье "Отличия методов POST или GET" . Если не указывать атрибут явно, по умолчанию будет использоваться метод GET.

Текст "Значение А:" и "Значение Б:" добавлен только с целью оформления и понятности формы для пользователя. Добавлять это для передачи данных не обязательно, но для того, чтобы пользователю стало понятно, что вводить, стоит указывать.

Теги используются для формирования различных управляющих элементов формы.

type="text" – атрибут "type" определяет вид поля. В зависимости от того, какой тип указан, меняется и внешний вид элемента, и его назначение. Значение атрибута "text" указывает, что в браузере элемент будет отображаться однострочным текстовым полем, куда пользователь сможет ввести свою строку.

name="data1" – атрибут "name", указывает имя, вернее индекс данных в массиве, полученных сервером. Это обязательный параметр, по которому в php-обработчике можно будет затем получить доступ переданному значению. Имя может быть выбрано произвольно, однако, удобнее когда это значение имеет какой-то понятный смысл.

type="submit" – тег с таким значением параметра "type" будет отображаться на странице как кнопка. На самом деле на форме можно обойтись и без кнопки. Если, например, в форме есть текстовые поля, то отправку можно осуществить, просто нажав "Ввод" на клавиатуре. Но наличие кнопки делает форму более понятной.

value="Отправить" – в данном случае (для type="submit") определяет только надпись на кнопке. Для type="text", например, это будет текст, который будет выведен в текстовом поле.

В итоге, на странице этот код будет выглядеть приблизительно так:

Значение А:
Значение Б:

По нажатию на кнопку, будет выполнена отправка данных на указанную страницу, и если она существует и корректно работает, данные будут обработаны.

Обработка отправленных HTML формой данных в PHP

Отправленные описанным способом данные, помещаются в суперглобальные массивы $_POST, $_GET и $_REQUEST. $_POST или $_GET будут содержать данные в зависимости от того, каким методом осуществлялась отправка. $_REQUEST содержит отправленные данные любым из указанных методов.

$_POST, $_GET и $_REQUEST – это ассоциативные массивы, поля-индексы которых совпадают с атрибутами "name" тегов . Соответственно, для работы с данными в файле myform.php можно присвоить переменным значения элементов такого массива указав в качестве индекса имя поля:

// для метода GET
$a = $_GET["data1" ];
$b = $_GET["data2" ];

// для метода POST
$a = $_POST["data1" ];
$b = $_POST["data2" ];

// при любом методе
$a = $_REQUEST["data1" ];
$b = $_REQUEST["data2" ];

Проверка заполнения полей формы

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

if (empty ($_REQUEST["data1" ])) {
echo "Поле не заполнено" ;
} else {
echo "Поле было заполнено" ;
$a = $_REQUEST["data1" ];
}

Обычно этого решения достаточно. Если нужно вводить текст, то будет понятно, введен он или нет. Однако, если пользователь намеренно для вычислений введет ноль, то функция empty покажет, что значения нет. Поэтому для таких ситуаций лучше использовать функцию isset . Она будет явно проверять, заданно ли значение или нет.

if (isset ($_REQUEST["data1" ])) {
echo "Поле было заполнено" ;
$a = $_REQUEST["data1" ];
} else {
echo "Поле не заполнено" ;
}

Одной из самых востребованных функций на сайте является форма заявки или заказа, данные из которой отправляются на почту владельцу сайта. Как правило такие формы являются простыми и состоят из двух трех полей для ввода данных. Как же создать такую форму заказа? Здесь потребуется использование языка разметки HTML и языка программирования PHP.

Язык разметки HTML сам по себе несложен, нужно всего лишь разобраться в том как и где ставить те или иные теги. С языком программирования PHP все немного сложнее.

Для программиста создать такую форму не составит труда, а вот HTML верстальщику может показаться сложным некоторые действия.

Создаем форму отправки данных в html

Первая строка будет следующей

Это очень важный элемент формы. В нем мы указываем каким способом будут передаваться данные и какому файлу. В данном случае все передачется методом POST файлу send.php. Программа в этом файле соответственно должна принять данные, они будут содержаться в post массиве, и отправить их на указанный email адрес.

Вернемся к форме. Вторая строка будет содержать поле для ввода ФИО. Имеет следующий код:

Тип формы text, то есть пользователь сможет ввести или скопировать сюда текст с клавиатуры. Под параметром name содержится название формы. В данном случае это fio, именно под таким именем будет передаваться все, что пользователь введен в данноу поле. Параметр placeholder указывает на то, что будет записано в этом поле в виде пояснения.

Следующая строка:

Здесь практически все то же самое, но имя для поля указано email, а пояснении указано, чтобы пользователь в эту форму ввел свой адресс электронной почты.

Следующей строкой будет кнопка "отправить":

И последней строкой в форме будет тэг

Теперь соберем все вместе.





Теперь сделаем так, чтобы поля в форме стали обязательными для заполнения. Имеем следующий код:





Создаем файл, принимающий данные из HTML формы

Это будет файл с именем send.php

В файле на первом этапе нужно принять данные из пост массива. Для этого создаем две переменные:

$fio = $_POST["fio"];
$email = $_POST["email"];

Перед названиями переменных в php ставиться знак $, в конце каждой строки ставиться точка с запятой. $_POST это массив в который передаются данный из формы. В форме html при этом указан метод отправки method="post". Так, приняты две переменные из формы html. Для целей защиты своего сайта нужно провести эти переменные через несколько фильтров - функций php.

Первая функция преобразует все символы, которые пользователь попытается добавить в форму:

При этом новые переменные в php не создаются, а используются уже имеющиеся. Что сделает фильтр, он преобразует символ "<" в "<". Также он поступить с другими символами, встречающимися в html коде.

Вторая функция декодирует url, если пользователь попытается его добавить в форму.

$fio = urldecode($fio);
$email = urldecode($email);

Третей функцией мы удалим пробелы с начала и конца строки, если таковые имеются:

$fio = trim($fio);
$email = trim($email);

Существуют и другие функции, позволяющие отфильтровать переменные php. Их использование зависит от того, насколько вы опасаетесь того, что злоумышленник попытается добавить программный код в данную форму отправки данных на почту html.

Проверка данных, передаваемых от HTML формы в файл PHP

Для того, чтобы проверить, работает ли этот код, передаются ли данные можно просто их вывести на экран при помощи функции echo:

echo $fio;
echo "
";
echo $fio;

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

Отправляем полученные данные из формы HTML на почту при помощи PHP

Для отправки данных на почту нужно воспользоваться функцией mail в PHP.

mail("на какой адрес отправить", "тема письма", "Сообщение (тело письма)","From: с какого email отправляется письмо \r\n");

Например, нужно отправить данные на email владельца сайта или менеджера [email protected].

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

mail("[email protected]", "Заявка с сайта", "ФИО:".$fio.". E-mail: ".$email ,"From: [email protected] \r\n");

Необходимо добавить условие, которе проверит отправилась ли форма при помощи PHP на указанные адрес электронной почты.

if (mail("[email protected]", "Заказ с сайта", "ФИО:".$fio.". E-mail: ".$email ,"From: [email protected] \r\n"))
{
echo "сообщение успешно отправлено";
} else {
}

Таким образом программный код файла send.php, который отправит данные HTML формы на почту будет выглядеть следующим образом:

$fio = $_POST["fio"];
$email = $_POST["email"];
$fio = htmlspecialchars($fio);
$email = htmlspecialchars($email);
$fio = urldecode($fio);
$email = urldecode($email);
$fio = trim($fio);
$email = trim($email);
//echo $fio;
//echo "
";
//echo $email;
if (mail("[email protected]", "Заявка с сайта", "ФИО:".$fio.". E-mail: ".$email ,"From: [email protected] \r\n"))
{ echo "сообщение успешно отправлено";
} else {
echo "при отправке сообщения возникли ошибки";
}?>

Три строки для проверки, передаются ли данные в файл закомментированы. При необходимости их можно удалить, так как они нужны были только для отладки.

Помещаем HTML и PHP код отправки формы в один файл

В комментариях к этой статье многие задают вопрос о том, как сделать, чтобы и HTML форма и PHP код отправки данных на почту находились в одном файле, а не двух.

Для реализации такой работы нужно поместить HTML код формы в файл send.php и добавить условие, которое будет проверять наличие переменных в массиве POST (этот массив передается из формы). То есть, если переменные в массиве не существуют, то нужно показать пользователю форму. Иначе нужно принять данные из массива и отправить их адресату.

Давайте посмотрим как изменить PHP код в файле send.php:



Форма заявки с сайта


//проверяем, существуют ли переменные в массиве POST
if(!isset($_POST["fio"]) and !isset($_POST["email"])){
?>





} else {
//показываем форму
$fio = $_POST["fio"];
$email = $_POST["email"];
$fio = htmlspecialchars($fio);
$email = htmlspecialchars($email);
$fio = urldecode($fio);
$email = urldecode($email);
$fio = trim($fio);
$email = trim($email);
if (mail("[email protected]", "Заявка с сайта", "ФИО:".$fio.". E-mail: ".$email ,"From: [email protected] \r\n")){
echo "Сообщение успешно отправлено";
} else {
echo "При отправке сообщения возникли ошибки";
}
}
?>

Существование переменной в POST массиве мы проверяем PHP функцией isset(). Восклицательный знак перед этой функцией в условии означает отрицание. То есть, если переменной не существует, то нужно показать нашу форму. Если бы я не поставил восклицательный знак, то условие дословно означало бы - "если существует, то показать форму". А это неправильно в нашем случае. Естественно, что вы можете переименовать его в index.php. Если будуту переименовывать файл, то не забудьте переименовать название файла и в строке

. Форма должна ссылаться на эту же страницу, например index.php. В код я добавил заголовок страницы.

Частые ошибки, возникающие при отправке PHP формы с сайта

Первая, наверное самая популярная ошибка, это когда вы видите пустую белую страницу без сообщений. Это означает, что вы допустили ошибку в коде страницы. Вам нужно включить отображение всех ошибок в PHP и тогда вы увидите, где допущена ошибка. Добавьте в код:

ini_set("display_errors","On");
error_reporting("E_ALL");

Файл send.php должен запускаться только на сервере, иначе код просто не будет работать. Желательно, чтобы это был не локальный сервер, так как он не всегда настроен на отправку данных на внешний почтовый сервер. Если вы запустите код не на сервере, то вам отобразиться код PHP прямо на странице.

Таким образом, для корректной работы я рекомендую поместить файл send.php на хостинг сайта. Там, как правило, все уже настроено.

Еще одна частая ошибка, когда появляется оповещение "Сообщение успешно отправлено", а письмо не приходит на почту. В этом случае нужно внимательно проверить строку:

if (mail("[email protected]", "Заказ с сайта", "ФИО:".$fio.". E-mail: ".$email ,"From: [email protected] \r\n"))

Вместо [email protected] должен быть email адрес на который нужно отправить письмо, а вместо [email protected] должен быть существующий email данного сайта. Например для сайта сайт это будет . Только в этом случае письмо с данными из формы будет отправлено.

Итак, Друзья. Это последнее видео из раздела по изучению HTML-форм.

В прошлом видео уроке мы разобрались в различиях между методами GET и POST отправки данных. И создали файл, который предназначен для обработки данных из HTML-формы. И чтобы завершить окончательно изучение форм нам осталось научиться собирать и отправлять данные из формы.

В этом видео мы поговорим об обработчике данных формы, который как раз нужен для сбора данных из полей формы и последующей их обработки. В этом видео мы научимся не только собирать данные из полей, но и отправлять их на E-mail . Не будет никаких особенностей обработки данных и тому подобных вещей. Мы просто воспользуемся самым простым вариантом сбора и отправки данных. Отправлять данные будем на E-mail, который укажем в обработчике. Здесь же стоит напомнить, что обработчиком является файл в формате php . А так как мы изучаем HTML , о PHP мы поговорим очень кратко. И только рассмотрим конкретный пример отправки данных на E-mail.

Обработчик формы.

Как я упомянул выше, это файл в формате PHP , который с помощью различных функций, переменных и глобальных массивов сможет собрать данные из формы и отправить на наш почтовый ящик. Рассматривать будем самый простой и примитивный вариант обработчика формы. Он не будет осуществлять каких-либо проверок полей и тому подобных вещей. Единственное, что мы будем проверять в этом видео уроке, отправлено ли письмо с данными формы к нам на почту или что-то пошло не так.

Отправка данных на E-mail.

Обработчик данных представляет собой довольно не большой PHP-код, который примет все данные из полей формы, обработает их и отправит к нам на почту.

Для отправки данных формы на почту мы будем использовать функцию mail . С помощью функции мы можем указать E-mail, на который должны прийти все данные, тему письма и собственно само сообщение, которое будет состоять из собранных данных из формы.

Если говорить простым языком. То в этом видео уроке. Мы рассмотрим, как создать форму обратной связи на сайте , и сделать так чтобы она работала. И когда посетитель захочет нам что-то написать, мы будем получать его сообщение на электронный адрес. Все довольно просто на самом деле. Достаточно пройти раздел по изучению HTML-форм и посмотреть это видео, чтобы разобраться, как все это сделать на своем сайте.

Видео урок: Обработчик формы. Отправка данных на E-mail.

HTML-справочник и другие материалы можно и нужно скачать !

В следующем видео уроке мы начнем новый раздел, посвященный созданию таблиц в HTML. И узнаем,

Применение методов GET и POST в PHP трудно переоценить, поскольку эти методы встречаются практически на каждом сайте. Прежде чем изучать ниже описанный материал, советую ознакомится с html тегом . Рассмотрим каждый из этих методов в подробности.

Метод GET

Метод GET использует для передачи данных строку URL. Возможно, Вы обращали внимание на длинные и непонятные URLы. Например: function.php?login=Alex&email=dezyakin . В данном случае данные обрабатываются в function.php. После знака вопроса "? " идет перечисление передаваемых параметров (параметр разделяются знаком "&") со значениями: параметру login присвоено значение Alex, а переменной email значение dezyakin. Данные будут хранится в суперглобальном массиве $_GET . Приведем пример использования метода GET представлен ниже:

Login : E-mail : С помощью суперглобального массива $_GET выводим принятые значения: */ echo "
login = ". $_GET["login"] ; echo "
email = ". $_GET["email"] ; ?>

Обратите внимание на то, как мы считываем значения из суперглобального массива $_GET: $_GET["имя_переменной"] . В нашем примере имена переменных были объявлены в форме (name=login и name=email).

Совет :
Прежде чем обрабатывать полученные значения советую проверять их на существование через функции isset(имя_переменной) или empty(имя_переменной) - эти функции были рассмотрены в предыдущем уроке 2: переменные в PHP . Например:

проверка на существование с помощью isset: if isset ($_GET["login"] ) { операторы для обработки login ... } //или же проверить на существование с помощью empty: if empty ($_GET["email"] ) { операторы для обработки email ... } ?>

В форме можно указать имя файла, который будет обрабатывать передаваемые значения. Делается это с помощью атрибута формы action , которому можно присвоить адрес этого файла. По умолчанию этот файл присвоен текущему файлу (т.е. обрабатывается в файле, где и расположена форма). Приведем пример, в котором данные из формы передаются на обработку в файл srcipt.php :

Login : E-mail :

В файле script.php должен содержатся какой-то обработчик информации, иначе информация будет передана в пустую.

Метод GET обладает множеством недостатков:

  • Пользователь видит значения передаваемых параметров;
  • Пользователь может легко подделать передаваемые параметры;
  • Неудобная передача бинарной информации (приходится кодировать в текстовый формат);
  • Объем передаваемых данных ограничен - 8 Кбайт;

Из-за выше перечисленных недостатков метод GET применяется только в тех случаях, когда нужно передать небольшой объем данных, а также эти данные никак не засекречены.

Метод POST

Метод POST отличается от GET тем, что данные передаются в закрытой форме. Существует суперглобальный массив $_POST , из которого можно считывать данные следующим образом: $_POST["имя_переменной"] . Например:

Login : "> E-mail : ">
С помощью суперглобального массива $_POST выводим принятые значения: */ echo "
login = ". $_POST["login"] ; echo "
email = ". $_POST["email"] ; ?>

Результат выполнения выше описанного кода представлен на рисунке ниже:

Как видите URL не имеет никакой приписки, но тем не менее данные были получены и выведены.

Примечание :
1) Объем передаваемых значений методом POST по умолчанию ограничен и равен 8 Мбайт. Чтобы увеличить это значение нужно изменить директиву post_max_size в php.ini.

2) В ранних версиях PHP вместо коротких названий суперглобальных массивов $_GET и $_POST использовались более длинные имена: $HTTP_GET_VARS и $HTTP_POST_VARS . По умолчанию они выключены в php 5, но Вы можете их включить в конфигурационном файле php.ini с помощью параметра register_long_arrays . В php 6 версии эти длинные названия будут недоступны.

3) Перед обработкой переменных из $_POST , советую проверять переменные на их наличие, также как это делалось с методом GET .

Многие веб приложения используют формы чтобы для сбора данных и отправки данных на сервер. Формы обычно содержат несколько элементов для ввода данных различного типа, например имени, адреса, даты рождения email адрес и так далее. HTML поддерживает несколько типов элементов ввода включая текстовые поля, радио кнопки и чекбоксы. В HTML5 добавлено больше специальных элементов, таких как email, поле для пароля, выбор цвета, виджеты для отображения даты и времени, бегунки.

Главный пример этого руководства содержит клиенскую и серверную часть. Клиентская часть использует Polymer для предоставления пользовательского интерфейса (формы содержат множество типов элементов ввода) и интерфейс синхронизации данных с Dart. Клиент и сервер общаются используя некоторые классы из различных библиотек, включаю потоки, флючерсы, HttpRequest и так далее. Сервер использует заголовки CORS для использования кросс-доменных запросов.

Замечание эта статья основывается на том что вы прочитали в разделах: Cоздание собственных элементов , Использование API для фьючерсов Динамическая обработка данных , а так же вы должны быть знакомы с библиотекой Polymer, фьючерсами, JSON и HttpRequest.

Общая информация о формах

У форм есть свойство action , представляющий собой URL для отправки данных формы, и method который определяет как данные должны быть отправлены. Свойства action и method могут быть определены непосредственно в HTML, или в более сложном случае или чтобы получить больше контроля, Вы можете написать код Dart и использовать библиотеки Dart для предоставления этих свойств программно

Давайте начнем с основ, только с HTML форм, чтобы разобраться в свойствах action и method элементов ввода и понять стандартное поведение форм. Форма ниже, заключенная в тэг

, используется для поиска данных, введенных пользователем, в Google. Информация ищется по сайту, если чекбокс выбран (и в интернете если нет). Этот пример, названный search_form, по умолчанию ищет полезные ресурсы “cookbook” на сайте dartlang.org.

вот HTML код для создания формы:

Использование атрибутов action и method.

А вот HTML код которые добавляет в форму три элемента ввода - текстовое поле, кнопка отправки и чекбокс.

Чекбокс обернут в тэг label, поэтому вы можете нажимать как на сам чекбокс так и на заголовок, чтобы изменить значение.

Этот HTML код предоставляет некоторое автоматическое поведение.

****

Создает специальную кнопку, нажатие которой вызывает отправку данных формы. На основании атрибутов action и method, кнопка формирует запрос и отправляет его на сервер по указанному URL.

**name=q** **name="sitesearch"**

определяет имя текстового поля и имя чекбокса.

Для элементов внутри формы, у которых указано имя предоставляют данные для этой формы. В данном примере, значение предоставляемое текстовым полем это значение для q , а чекбокс предоставляет значение для sitesearch , оба этих параметра являются частью корректного URL для запроса Google. Когда пользователь нажимает кнопку, имя и соответствующее значение добавляется к URL для поиска. Вот пример запроса:

Http://www.google.com/search?q=Cookbook&sitesearch=dartlang.org

Этот пример полностью создан без использования кода Dart или Javascript. Потому как он очень прост, он может использовать обычное поведение HTML: публично доступный и прост для формирования URL, а так же обычный GET запрос. Для форм, которые содержать большое количество данных, или для web приложения, которое общается со специализированным сервером, вам обычно надо обрабатывать форму программно.

Следующий пример показывает более сложную форму, которая программно отправляет данные на сервер, используя POST запрос.

Пример slambook в частности

Этот раздел включает две программы в качестве основных примеров.

    Первая, это обычная серверная программа, названная slambookserver, которая слушает на локальном компьютере порт 4040 и обрабатывает запросы POST и OPTIONS создавая сообщения и отправляя подтверждение клиенту. Сервер использует заголовки CORS для того чтобы разрешить приложению использовать запросы отправленные с других серверов.

    Вторая, это клиентская программа, названная slambook, предоставляющая форму, в которой пользователь может вводить информацию. Эта программа использует Polymer для двойной связи данных, между элементами ввода и переменными Dart. Когда пользователь нажимает кнопку, код Dart преобразует данные в строку JSON, отправляет запрос OPTIONS чтобы получить разрешение сервера, а затем отравляет POST запрос для отправки данных. Когда запрос от сервера получен, он отображается клиенту.

Следующая диаграмма показывает последовательность общения между сервером и клиентом в данном примере.


Попробуйте! Введите любые данные и нажмите кнопку Отправить .

Замечание о версии . Приложение slambook совместимо с polymer.dart 0.9.

Запрос возвращает сообщение “No server” потому что вы не запустили сервер на своей машине. Давайте это исправим.

Запуск сервера

Исходный код основной серверной программы slambookserver.dart можно скачать из примеров руководства

Запустите серверную программу из командной строки

% dart slambookserver.dart Listening for GET and POST on http://127.0.0.1:4040

Теперь Вы снова можете попробовать отправить данные из приложения slambook выше.

Замечание : Если какая-то другая программа уже использует порт 4040, сервер вернет сообщение об ошибке и завершит выполнение. Программа на этой странице рассчитывает что slambookserver будет расположен на локальной машине, порт 4040. Поэтому чтобы приложение могло работать вы должны завершить другой процесс и снова запустить slambookserver. Или вы можете изменить номер порта в серверной и клиентской программе. Избегайте использования 3030, так как его использует Dart Editor. Затем запустите клиент и сервер на вашем локальном компьютере.

Оставшаяся часть этого руководства поясняет код сервера и клиента.

О клиентской части Вы узнаете об:

    Отправке данных формы

    Сброс формы

    Использовании Polymer для связи данных формы

Серверная часть в этом разделе расскажет о:

    Заголовках CORS

    Обработке запросов OPTIONS

    Обработке запросов POST

Отправка данных формы

Первым делом давайте взглянем на то как данные отправлены на сервер.

Напомним что пример search_form был основан на использовании атрибутов action и method для задания назначения и метода, для отправки формы. Также напомним что пример search_form основывается на автоматическом поведении специальной кнопки отправки. С другой стороны, пример slambook принимает непосредственное участие в процессе отправки:

    Во-первых в форме не определен ни action ни method

    Во-вторых у кнопки отправки данных есть обработчик нажатия в Dart

    В-третьих обработчик нажатия переопределяет автоматическое поведение кнопки отправки

    И наконец данные формы отправляются на сервер при помощи библиотек Dart

Форма в примере slambook представлена пользовательским элементом tute-slambook-form , который представлен следующим кодом HTML:

Обратите внимание на отсутствие атрибутов action и method. Вместо этого поведение кнопки отправки определено в обработчике нажатия кнопки в Dart. Ниже представлен HTML код, который создает кнопку отправки и связывает ее с обработчиком Dart.

А вод и сам код обработчика нажатия кнопки submitForm():


Давайте рассмотрим каждый элемент кода обработчика

Отмена стандартного обработчика

Это событие без атрибутов action и method , кнопка отправки содержит автоматическое поведение, которое не нужно в примере slambook. Поэтому в первой строке кода обработчика вызывается e.preventDefault(), чтобы отменить поведение кнопки по умолчанию.

Void submitForm(Event e) { e.preventDefault(); // Don"t do the default submit. … }

Настройка и отправка POST запроса

Следующая часть кода создает объект HttpRequest . В этом коде используется new чтобы создать экземпляр объекта HttpRequest, который используется чтобы настроить и отправить POST запрос. Класс HttpRequest имеет соответствующую функцию getString(), чтобы Вы могли использовать и отправлять обычные GET запросы к URL.

Следующая строка предоставляет объекту HttpRequest колбэк функцию, названную onData , которая вызывается при получении ответа от сервера. Мы рассмотрим детали объявления функции onData() позже.

Важно : Вы должны зарегистрировать колбэк функцию до отправки запроса!

Request = new HttpRequest(); request.onReadyStateChange.listen(onData); var url = "http://127.0.0.1:4040"; request.open("POST", url); request.send(slambookAsJsonData());

И наконец функция отправляет данные формы на сервер в виде JSON строки. Иногда данные отправляются по частям. Но этот пример достаточно мал, чтобы данные отправлялись за раз. Этот запрос является асинхронным, поэтому метод send() завершится как только запрос будет отправлен.

Ожидание ответа от сервера

Объект HttpRequest общается с сервером. Вы можете получить состояние используя поле readyState объекта HttpRequest. Состояние готовности может принимать пять различных значений: не отправлено (unsent), открыто (opened), заголовки получены (headers received), загрузка (loading) и выполнено (done). Когда состояние готовности меняется, HttpRequest вызывает событие, и вызывается колбэк функция onData().

Напомним строчку кода, в которой регистрируется обработчик события onReadyStateChange :

Request.onReadyStateChange.listen(onData);

Единственным требуемым аргументом метода listen() является колбэк функция с сигнатурой: void onData(T) . Метод listen() также позволяет вам определить три дополнительных аргумента, например обработчик ошибок.

Ниже колбэк функция onData():

Void onData(_) { if (request.readyState == HttpRequest.DONE && request.status == 200) { // Data saved OK. serverResponse = "Server Sez: " + request.responseText; } else if (request.readyState == HttpRequest.DONE && request.status == 0) { // Status is 0...most likely the server isn"t running. serverResponse = "No server"; } }

Первым делом в коде проявляется завершился ли успешно запрос. Если да то содержание ответа помещается в строку названную serverResponse , которая привязана к значению элемента textarea приложения slambook. При изменении строки интерфейс пользователя будет автоматически обновлен, о сообщение будет показано пользователю.

Если запрос выполнен с ошибкой, то программа выведет в serverResponse сообщение об ошибке, которое будет показано пользователю.

Сброс данных из формы

Кнопка сброса это специальный элемент ввода HTML, который по умолчанию очищает значения введенные в эту форму. Мы же вместо этого хотим чтобы кнопка сбрасывала значения формы к первоначальным. Поэтому, обработчик нажатия для кнопки сброса нуждается в отмене автоматического поведения и явно заполнить данные.

Void resetForm(Event e) { e.preventDefault(); favoriteThings["kittens"] = false; favoriteThings["raindrops"] = false; favoriteThings["mittens"] = false; favoriteThings["kettles"] = false; theData["firstName"] = ""; theData["favoriteQuote"] = ""; theData["favoriteColor"] = "#FFFFFF"; theData["birthday"] = "2013-01-01"; theData["volume"] = "0"; theData["catOrDog"] = "cat"; theData["music"] = 0; theData["zombies"] = false; serverResponse = "Data reset."; }

Создание серверной части и прослушивание порта

Теперь давайте обратим рассмотрим серверную часть, которая называется slambookserver , она возвращает HTTP ответ, на запрос отправленный из клиентского приложения slambook. Код серверной части основывается на статье [Использование Dart для создания JSON Web сервисов (#)

Сервер слушает порт 4040 на локальной машине и обрабатывать только запросы типа POST и OPTIONS. Оба типа запросов используют для разрешения доступа CORS заголовки. Для POST запросов, сервер возвращает короткое сообщение о подтверждении, которое включает данные в формате JSON которые он получил из запроса.

Давайте взглянем на код.

Функция main() приложения slambookserver приведена полностью чуть ниже. Используя класс HttpServer приложение slambookserver начинает прослушивание порта 4040 локальной машины после вызова функции верхнего уровня bind ()

Final HOST = "127.0.0.1"; final PORT = 4040; void main() { HttpServer.bind(HOST, PORT).then(gotMessage, onError: printError); }

Функция bind() возвращает фьючерс, при помощи которого можно получить значение в будущем (больше информации будет буквально через минуту). Функция then() регистрирует две колбэк функции в виде фьючерса. Первая функция gotMessage(), вызывается когда фьючерс получает значения. Вторая printError вызывается при неудачной попытке соединения. Ошибка может возникнуть, например, если другая программа уже слушает тот-де порт.

Фильтрация запросов и вызов остальных методов для обработки каждого типа запроса функции gotMessage () ниже.

Void gotMessage(_server) { _server.listen((HttpRequest request) { switch (request.method) { case "POST": handlePost(request); break; case "OPTIONS": handleOptions(request); break; default: defaultHandler(request); } }, onError: printError); // Listen failed. print("Listening for GET and POST on http://$HOST:$PORT"); }

Для обработке других типов запросов, таких как GET, вы можете просто добавить больше значений в case например case ‘GET’ .

Немного о фьючерсах.

Давайте немного рассмотрим фьючерсы, до того как будем разбираться с кодом обработки POST и OPTIONS запросов.

Фьючерс представляет способ получения значения через некоторое время в будущем. Вы используете фьючерсы для предотвращения блокировки программы пока она ожидает данные, например если необходимы долгие вычисления для предоставления значения, или если значение должно быть прочитано или получено с использованием ввода/вывода.

Когда вызывается функция возвращающая фьючерс, происходит две вещи

    Функция помещается в очередь на выполнение и немедленно возвращает незавершенный объект фьючерс.

    Позже, когда значение получено, объект фьючерса завершается с полученным значением или с ошибкой.

Чтобы получить значение возвращаемое фьючерсом используется метод then () для регистрации колбэка.

В этом примере и клиентская и серверная часть использует фьючерсы для отправки запросов и получения соответствующих ответов. Программы типа клиент-сервер почти всегда используют фьючерсы для общения и других видов асинхронного ввода вывода.

Обработка запросов OPTIONS

С помощью класса HttpRequest , клиентское приложение slambook отправляет запросы, когда пользователь нажимает кнопку “отправить”. Вы видели код ранее в этой статье.

Если клиента и сервера различное происхождение, что является общим в приложениях, перед POST отправляется предварительный запрос. Предварительный запрос должен в первую очередь содержать OPTIONS запрос чтобы определить какие вообще запросы разрешены. Класс HttpRequest автоматически обрабатывает предварительные запросы OPTIONS. Вам больше не надо для этого писать код на стороне клиента.

Сервер получает предварительный запрос OPTIONS до того как получает основной запрос. Вот код приложения slambookserver который обрабатывает OPTIONS запросы.

Void handleOptions(HttpRequest req) { HttpResponse res = req.response; addCorsHeaders(res); print("${req.method}: ${req.uri.path}"); res.statusCode = HttpStatus.NO_CONTENT; res.close(); }

Этот код выполняет следующее:

    Получает объект HttpResponse, который заботится о том чтобы сервер послал ответ клиенту

    Добавляет CORS заголовки для управления доступом

    Выводит сообщение в консоль

    Сигнализирует о том, что у ответ нет содержания

    Завершает ответ, который будет отправлен клиенту.

Когда клиент получает запрос, CORS заголовок сигнализирует о том, запросы POST будут приняты.

Настройка CORS заголовков

Серверное приложение использует следующую функцию для добавления в ответ CORS заголовков для OPTIONS и POST запросов. Функция добавляет ответ сервера три заголовка Access-Control (которые включаются в ответ HttpResponse).

Void addCorsHeaders(HttpResponse res) { res.headers.add("Access-Control-Allow-Origin", "*, "); res.headers.add("Access-Control-Allow-Methods", "POST, OPTIONS"); res.headers.add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); }

Первые две строки CORS заголовка разрешают запросы POST и OPTIONS из любых источников. Третий определяет тип запросов POST и OPTIONS сервер разрешает принимать запросы только с определенными заголовками.

Обработка POST запросов

Вот функция, которая обрабатывает клиентские POST запросы.

Void handlePost(HttpRequest req) { HttpResponse res = req.response; print("${req.method}: ${req.uri.path}"); addCorsHeaders(res); req.listen((List buffer) { // Return the data back to the client. res.write("Thanks for the data. This is what I heard you say: "); res.write(new String.fromCharCodes(buffer)); res.close(); }, onError: printError); }

Так же как и запрос OPTIONS, slambookserver получает объект HTTP ответа из запроса, выводит сообщение в консоль и добавляет CORS заголовки к ответу.

Далее в этом коде прослушиваются данные из клиентского запроса POST. Если все данные готовы, вызывается колбэк функция. Эта функция написана в то же месте. Аргументом функции является список чисел, включающий все данные. Каждое число представлено кодом, который может быть представлен в виде символа UTF-16. Но вам не надо беспокоиться об этом, потому что Вы можете просто вызвать метод String.fromCharCodes для конвертации в обычную строку.

Объект HttpResponse управляет потоками данных который сервер может использовать для отправки данных обратно клиенту. Внутри колбэк функции, slambookserver пишет в этот поток сообщения и исходные данные в виде строки. Более сложные серверы будут что-то делать с этими данными, например сохранять их на сервере, обрабатывать, или может даже снимать деньги с вашего счета в банке.

При закрытии потока, объект HttpResponse отправляет данные клиенту.

Пример клиент-серверного приложения slambook может послужить отправной точкой для Вашего собственного клиент-серверного приложения или примером того, как надо строить свои собственные приложения.

Вот образец того что должна выполнять клиентская часть.

    Использовать формы для сбора данных пользователя.

    Помещать поля ввода в ваши формы, для отдельных элементов данных.

    Использовать Polymer для обратной связи, чтобы данные формы были синхронизированы с кодом Dart.

    Отправлять данные напрямую (свойства формы action и method)

    Или программно (переопределяя стандартное поведение кода Dart кнопки отправки)

    Создавать объект ответа на сервере из объекта HttpRequest.

А вот что должен делать сервер.

    Использовать HttpServer для настройки сервера и прослушивания порта.

    Обрабатывать ответы.

    Использовать заголовки CORS чтобы разрешить каждый запрос.

    Ответ на запрос использует HttpResponse.

    Обрабатывать данные асинхронно используя фьючерсы.

Использовать потоки для записи данных в ответ.

Эти ресурсы по большей части на основе библиотек Dart, предоставляющих поддержку для написания клиентов и серверов. Учтите что бывает два класса HttpRequest: один в dart:html (для клиентов) и второй dart:io (для серверов).

Ресурс Библиотека Описание
HttpRequest dart:html Клиентская часть HTTP запроса
HttpRequest dart:io Серверная часть HTTP запроса
HttpServer dart:io Серверная часть обрабатывающее HTTP связь с сервером
HttpResponse dart:io Серверная часть которая заботится об отправке ответов на запрос
Streams dart:async Поток данных
Future dart:async Способ получать данные асинхронно
JSON dart:convert Объявление преобразования в JSON по умолчанию
Polymer Polymer Пользовательские элементы, данные связанные с шаблоном

Двухсторонняя привязка данных используя Polymer

Пример slambook использует Polymer для обратной связи, значения элемента ввода с переменными Dart. Если пользователь меняет значение элемента ввода, связанная переменная в коде Dart меняется автоматически. Или если значение меняется в коде Dart, связанный объект пользовательского элемента обновляется автоматически. Статья определение пользовательских элементов предоставит больше деталей о связывании данных и о Polymer.

Этот пример так же использует объявление обработки событий для перехватывания и обработки функций для элементов ввода.

При помощи примера slambook вы можете рассмотреть используется двунаправленное связывание данных для различных элементов ввода, включая новые элементы HTML5. Эта таблица объединяет все двунаправленные атрибуты, которые вы можете использовать с помощью Polymer:

Использование атрибута value в любом элементе ввода

Атрибут value работает в любых элементах ввода и связывает значение со строкой Dart. Этот пример использует value для тактового поля, поля ввода текста, выбора цвета, выбора даты и выбора диапазона.


(Отметим что некоторый код вокруг, например

Словарь в коде Dart названный theData содержит данные формы. Код объекта словаря выделяется при помощи @observable и вызывает toObservable() для связывания.

Словарь содержит пары ключ/значение для каждого элемента ввода, где ключ является строкой. Значения элементов связанных с value являются строками. HTML ссылается на элементы словаря используя их имена (идентификаторы) в Dart. Например значение элемента выбора цвета связано с theData[‘favoriteColor’] .

Использование selectedIndex в выпадающем меню

Элемент