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

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

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

Предварительные знания

Базовая компьютерная грамотность, понимание HTML и базовые знания по HTTP и программированию на стороне сервера.

Задача

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

Куда отправляются данные?

Здесь мы обсудим, что происходит с данными при отправке формы.

О клиентской/серверной архитектуре

WEB основан на очень простой клиент-серверной архитектуре, которую можно обобщить следующим образом: клиент (обычно веб-браузер) отправляет запрос на сервер (в основном веб-сервер, такой как Apache, Nginx, IIS, Tomcat, и т. д.), используя протокол HTTP. Сервер отвечает на запрос, используя тот же протокол.

На стороне клиента HTML-форма – это не более чем удобный способ настройки HTTP-запроса для отправки данных на сервер. Это позволяет пользователю предоставлять информацию для доставки в HTTP-запросе.

Определение способа отправки данных

Этот атрибут определяет, куда отправляются данные. Его значение должно быть действительным URL.

  • Если этот атрибут не указан, данные будут отправлены на URL-адрес страницы, содержащей форму.

В этом примере данные отправляются на абсолютный URL — http://foo.com.

Здесь мы используем относительный URL – данные отправляются на другой URL на сервере.

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

Примечание: Можно указать URL, который использует протокол HTTPS (безопасный HTTP). Когда вы делаете это, данные шифруются вместе с остальной частью запроса, даже если сама форма размещается на небезопасной странице, доступ к которой осуществляется через HTTP. С другой стороны, если форма размещается на защищённой странице, но вы указываете небезопасный URL-адрес HTTP с атрибутом action, все браузеры выдают пользователю предупреждение о безопасности при каждой попытке отправки данных, поскольку данные не шифруются.

Атрибут method

Этот атрибут определяет способ отправки данных. Протокол HTTP предоставляет несколько способов выполнить запрос;

  • Данные HTML-формы могут передаваться несколькими различными способами, наиболее распространёнными из которых являются метод GET и метод POST.

Чтобы понять разницу между этими двумя методами, давайте вернёмся назад и рассмотрим, как работает HTTP. Каждый раз, когда вы хотите получить доступ к ресурсу в Интернете, браузер отправляет запрос на URL-адрес. HTTP-запрос состоит из двух частей: заголовка, который содержит набор глобальных метаданных о возможностях браузера, и тела, которое может содержать информацию, необходимую серверу для обработки конкретного запроса.

Метод GET

Метод GET – это метод, используемый браузером, который говорит серверу, что нужно отправить назад данный ресурс: Эй, сервер, я хочу получить этот ресурс. В этом случае браузер отправляет пустое тело. Поскольку тело пустое, если форма отправляется с использованием данного метода, данные, отправляемые на сервер, добавляются к URL-адресу.

Пример использования метода GET

Поскольку используется метод GET, при отправке формы появляется URL www.foo.com/?say=Hi&to=Mom в адресной строке браузера.

Данные добавляются в URL как последовательность пар имя / значение. После знака вопроса (?) следуют пары имя / значение, каждая из которых разделена амперсандом (&).

HTTP-запрос выглядит следующим образом:

GET /?say=Hi&to=Mom HTTP/2.0 
Host: foo.com

Метод POST

Метод POST немного отличается. Браузер использует этот метод для связи с сервером при запросе ответа с учётом данных, представленные в теле HTTP-запроса: Эй, сервер, взгляни на эти данные и отправь мне соответствующий результат. Если форма отправляется с использованием этого метода, данные добавляются в тело HTTP-запроса.

Пример использования метода POST

Когда форма отправляется с использованием метода POST, данные добавляются в тело запроса, а не к URL-адресу.

HTTP-запрос выглядит следующим образом:

POST / HTTP/2.0
Host: foo.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13

say=Hi&to=Mom

Заголовок Content-Length указывает размер тела, а заголовок Content-Type указывает тип данных, отправляемых на сервер.

Просмотр HTTP-запросов

HTTP-запросы обычно не отображаются пользователям, но вы можете использовать инструменты, такие как Firefox Network Monitor или Chrome Developer Tools, чтобы просматривать их. Например, данные формы можно увидеть на вкладке Сеть (Network) в Chrome после отправки формы.

## Единственное, что отображается пользователю — вызываемый URL
Как упоминалось раннее, запрос с методом GET позволит пользователю увидеть информацию из запроса в URL, а запрос с методом POST не позволит. Две причины, почему это может быть важно:

## На стороне сервера

Какой бы HTTP вы не выбрали, сервер возвращает строку, которая будет последовательно проанализирована для получения данных в формате листа с парами ключ/значение. Способ получения доступа к этому листу зависит от платформы разработки или особенностей фреймворка, который вы можете использовать. Технологии, которые вы используете, определяют, как обрабатываются скопированные ключи. Часто, приоритетным является последнее полученное значение для данного ключа.

### Чистый PHP

PHP предлагает несколько глобальных объектов для доступа к данным. Например, вы используете POST-метод, в приведённом ниже примере данные просто получаются и показываются пользователю. Разумеется, как использовать данные — решать только вам. Вы можете отобразить эти данные, поместить в базу данных, отправить по почте или передать эти данные куда-либо ещё.

Пример показывает страницу с данными, которые мы отправили. Вы можете посмотреть это в действии в нашем файле с примером: php-example.html — который содержит те же данные, которые вы видели раньше: method : post и action из php-example.php. Когда данные переданы на отправку (submit), они переданы в форму php-example.php, которая содержит PHP код из примера выше. Когда код будет выполнен, браузер выведет (output) обработанное сообщение: Hi Mom.

![PHP Example](https://developer.mozilla.org/ru/docs/Learn/Forms/Sending_and_retrieving_form_data/php-result.png)

_Примечание: Этот пример не будет работать, когда вы загружаете его в браузер локально — браузер не может интерпретировать PHP код, после отправки данных из формы, браузер просто предложит загрузить PHP файл. Чтобы пример заработал, необходимо отправить его на PHP сервер. Для тестирования PHP на локальных серверах можете пробовать MAMP (Mac and Windows) и/или AMPPS (Mac, Windows, Linux).

### Python

Этот пример показывает, как вы можете использовать Python для решения той же задачи — отобразить отправленные данные на странице. В этом примере используется Flask framework для визуализации шаблонов, поддерживающих форму отправки данных (смотри python-example.py).

```python
from flask import Flask, render_template, request

app = Flask(__name__)

@app.route(/method, methods=[GET, POST])
def sayrequestform():
    if request.method == POST:
        return render_template(php-result.html, to=request.form[name])
    return render_template(php-example.html)

if __name__ == __main__:
    app.run()

Два шаблона из коде выше взаимодействуют так:

_Примечание: Опять же, этот код не будет работать, если вы просто попробуете загрузить его прямо в браузер. Python работает немного иначе, чем PHP — чтобы запустить этот код, нужно установить Python/PIP, потом установить Flask используя команду: pip3 install flask. После этого, вы сможете запустить файл из примера, используя команду: python3 python-example.py, потом открыть localhost:5000 в своём браузере.

Другие языки и фреймворки


## Фреймворки
Существует множество других серверных технологий, которые вы можете использовать для работы с формами, включая языки Perl, Java, .Net, Ruby и прочее. Выбирайте тот, который нравится больше. К тому же, использовать вышеупомянутые технологии непосредственно, без использования фреймворков, может быть сложно. Лучше использовать один из множества высококачественных фреймворков, таких как:
- Bootstrap
- Django
- React
- Angular
Стоит отметить, что использование фреймворков и работа с формами - это не всегда легко. Но это намного легче, чем пытаться написать аналогичную функциональность с нуля, и это определённо сэкономит время.
## Отправка файлов
Отправка файлов с помощью форм HTML — это особый случай. Файлы — это бинарные данные или рассматриваются как таковые, в то время как все остальные — это текстовые данные. Поскольку HTTP — это текстовый протокол, есть особые требования для работы с бинарными данными.
### Атрибут enctype
Этот атрибут позволяет конкретизировать значение в Content-Type HTTP заголовок, включённый в запрос, при генерировании отправки формы. Этот заголовок очень важен, потому что указывает серверу, какой тип данных отправляется. По умолчанию это: application/x-www-form-urlencoded. На человеческом это значит: Это форма с данными, которые были закодированы в URL параметры.
Если хотите отправить файл, нужно сделать следующие три шага:
1. Выбрать файл
2. Отправить файл
Предупреждение: Многие сервера имеют заданные ограничения на размер загружаемых файлов и запросы от пользователей, чтобы защититься от возможных злоупотреблений. Важно проверять эти ограничения у администратора сервера, прежде чем загружать файлы.
### Проблемы безопасности
Каждый раз, когда вы отправляете данные на сервер, вы должны учитывать безопасность. HTML-формы являются наиболее распространёнными векторами атак на серверы(места, где могут происходить атаки). Проблемы вытекают не из самих форм HTML, а из-за того, как сервер обрабатывает данные из этих форм.
В зависимости от того, что вы делаете, вы можете столкнуться с некоторыми очень известными проблемами безопасности:
### XSS Межсайтовый скриптинг и CSRF Подделка межсайтовых запросов
Межсайтовый скриптинг (XSS Cross Site Request Forgery) и подделка межсайтовых запросов (CSRF Cross-Site Scripting) - это распространённые типы атак, которые происходят при отображении данных после ответа сервера или другого пользователя.
Межсайтовый скриптинг (XSS Cross Site Request Forgery) позволяет злоумышленникам внедрить клиентский скрипт в веб-страницы, просматриваемые другими пользователями. Подделка межсайтовых запросов (CSRF Cross-Site Scripting) может использоваться злоумышленниками для обхода средств контроля доступа, таких как одна и та же политика происхождения. Последствие от этих атак может варьироваться от мелких неудобств до значительного риска безопасности.
CSRF-атаки аналогичны XSS-атакам в том, что они начинаются одинаково - с внедрения клиентского скрипта в веб-страницы - но их конечные цели разные. Злоумышленники CSRF пытаются назначить права пользователям с более высоким уровнем прав доступа(например, администратору сайта), чтобы выполнить действие, которое они не должны выполнять (например, отправка данных ненадёжному пользователю). Атаки XSS используют доверие пользователя к веб-сайту, в то время как атаки CSRF используют доверие веб-сайта к пользователю.
### SQL - вброс
SQL -вброс представляет собой тип атак, при которых осуществляется попытка выполнения действия с базой данных, используемой целевым веб-сайтом. В этих случаях обычно осуществляется отправка SQL-запроса в надежде, что сервер выполнит этот запрос (обычно при попытке сервера приложения сохранить данные, отправляемые пользователем). Данный вид атак является одним из самых направленных атак на веб-сайты.
Последствия могут быть ужасающими, начиная от потери данных и заканчивая утратой контроля над всей инфраструктурой веб-сайта за счёт повышения привилегий. Это очень серьёзная угроза, поэтому никогда не сохраняйте данные, отправляемые пользователем, без выполнения фильтрации данных (например, с помощью mysqli\_real\_escape\_string().
### Вброс HTTP-заголовка и email
Эти виды атак могут проявляться, когда ваше приложение создаёт заголовки HTTP или электронные почтовые адреса на основании данных, введённых пользователем в форму. Такие атаки напрямую не повреждают сервер или пользователей, однако создают уязвимость для таких угроз, как перехват сессии, или для фишинговых атак.
Такие атаки являются самыми незаметными, но при этом могут превратить ваш сервер в зомби.
### Никогда не доверяйте вашим пользователям
Как вы боретесь с такими угрозами? Этот вопрос выходит далеко за рамки данной статьи, но есть несколько общих правил, которые следует всегда соблюдать. Самое важное из них - никогда не доверяйте вашим пользователям, в том числе себе; даже проверенный пользователь может быть атакован.
Все данные, поступающие на ваш сервер, необходимо проверять и санитизировать. Все и всегда. Без исключений.
Соблюдая эти три правила, вы сможете избежать многих/большинства проблем. При этом следует помнить, что периодически необходимо проводить анализ защищённости, желательно квалифицированной сторонней организацией. Не считайте, что вы уже сталкивались со всеми возможными угрозами.
Примечание: В статье Безопасность веб-сайта нашего раздела серверного обучения приведено подробное обсуждение упомянутых угроз и возможных способов их устранения.
## Заключение
Как мы увидели, отправлять формы просто, однако защитить приложение может быть довольно трудно. Просто помните, что фронтенд разработчики не должны задавать модель безопасности для приложения. Да, как мы увидим далее, мы можем проверить данные на стороне клиента, однако сервер не может доверять этой проверке, потому что он никогда не может по-настоящему узнать что происходит на стороне клиента.
Для создания этого удобного инструмента необходимо перейти в раздел «Интеграция» - «CRM-формы».
![](https://www.1c-kpd.ru/upload/medialibrary/481/w6yannvmu0p1li4rkga3l0scyjuyc6m5.jpg)  
Откроется список уже созданных форм. В правой части окна мы видим показатели конверсии формы и изменения за последние 2 недели. Для создания новой формы нажмем кнопку «Создать».
![](https://www.1c-kpd.ru/upload/medialibrary/635/6rtqftvl5rtckbzskcaaoluft3miro4x.jpg)  
В Битрикс24 представлена большая подборка CRM-форм для всех основных вариантов взаимодействия с клиентами. Выбирая вид формы в левой части экрана, мы будем видеть состав ее полей в правой.
![](https://www.1c-kpd.ru/upload/medialibrary/fb2/bc6tqpf8j6jz2s6undgp196lunttfz3i.jpg)  
Создадим свою уникальную CRM-форму. Для этого опустимся в самый низ списка и выберем «Индивидуальная настройка».
Настроим поля формы. Мы можем добавлять или удалять поля, менять их местами или переименовывать. Нажмем «Добавить поле» для создания нового поля.
![](https://www.1c-kpd.ru/upload/medialibrary/592/fm7q360aw1nfzk8tg7qgn8c6qf213fm3.jpg)  
В левой части окна представлены элементы CRM, а в правой присущие им поля, есть возможность создать новое поле.
![](https://www.1c-kpd.ru/upload/medialibrary/fb0/elqm71s8t0aqzphplqf6ppdaswkcitj8.jpg)  
Перейдем к пункту меню «Соглашения» - это важный для заполнения пункт, т.к. в нем прописывается соглашение на обработку персональных данных клиента согласно 152-ФЗ от 27.07.2006\. Вы можете выбрать из существующих вариантов или написать собственный.
![](https://www.1c-kpd.ru/upload/medialibrary/d23/nermfwl6j6edii42yedznd6a178nq0y4.jpg)  
Далее нам необходимо выбрать, какой элемент CRM будет создан при заполнении формы. В экспертном режиме настройки зададим объединение дубликатов при обнаружении – это наиболее безопасный с точки зрения сохранности информации метод.
![](https://www.1c-kpd.ru/upload/medialibrary/c5e/fpvpf8api6n16cbhhdkrkt03wsf9twp6.jpg)  
Составим заголовок и подзаголовок к нашей форме, напишем текст на кнопке для отправки CRM-формы.
![](https://www.1c-kpd.ru/upload/medialibrary/b76/i8gx2mq7rnvgf50wb6zznk05lj0wb0ng.jpg)  
В меню «Правила показа полей» мы можем запрограммировать видимость одних полей от других. Рассмотрим на примере настройки «Разные значения полей управляют разными полями».
![](https://www.1c-kpd.ru/upload/medialibrary/5b7/n622zu6maxjrr3rvkw02j1tle7pan03o.jpg)  
Логика будет следующая: Если заполнено значение поля «Телефон», то в CRM-форме появится поле «E-mail».
![](https://www.1c-kpd.ru/upload/medialibrary/1ce/5znbkhgvwwepmrs6cbryqx3dcan7niak.jpg)  
Далее выберем какое действие произойдет после отправки формы.
![](https://www.1c-kpd.ru/upload/medialibrary/e2c/my7dn0g1dqx45s2jrikyy01ul9wugh6g.jpg)  
Рассмотрим вариант с сообщением, как наиболее простой. Текст можно изменить на более подходящий нам.
![](https://www.1c-kpd.ru/upload/medialibrary/e19/75viw44f4y3w12zfihy0a9srzwm137z8.jpg)  
Вариант «Редирект», т.е. перенаправление позволит открыть клиенту указанную интернет страничку, например, с нашими тарифами или акциями.
![](https://www.1c-kpd.ru/upload/medialibrary/d17/eqarlneezqg0b221uhu0yiygi2yvzjm1.jpg)  
В «Другие настройки» мы можем дать название нашей форме и установить ответственных за обработку поступающих данных.
![](https://www.1c-kpd.ru/upload/medialibrary/a6a/myf2pz66pym8nkqcwfe2foyr3artx2oa.jpg)  
Меню дизайн позволяет разукрасить и стилизовать форму по нашему усмотрению.
![](https://www.1c-kpd.ru/upload/medialibrary/973/dk9yiyddvoozb687wy1a5e5l5zccat81.jpg)  
После сохранения мы сможем использовать форму на нашем сайте, других ресурсах или прикрепляя ее в виде ссылки в различные материалы.
![](https://www.1c-kpd.ru/upload/medialibrary/4b5/b39astmowbl8s2aax449jlsdxwthl6l5.jpg)  
Использование CRM-форм значительно упрощает сбор первичной информации менеджерами и автоматизирует часть процесса продаж. Широкие возможности по настройке форм, позволяют использовать их и для внутренних нужд компании, например, в HR и корпоративных мероприятиях.
Помимо стандартных средств работы с формами можно использовать JavaScript, чтобы проверять формы на валидность, получать доступ к значениям и отправлять информацию на сервер.
Трюки для работы с формами в JS проще всего показать на примере. В этой статье мы соберём форму заявки на участие в миссии по колонизации Марса. В этой форме мы немножко приправим стандартные HTML-атрибуты динамикой на JS.
## Разметка и требования
Наша форма заявки на участие в миссии «Mars Once» будет состоять из шести полей. В форме мы собираем следующие данные:
Открыть демо в новой вкладке
В целом форма рабочая: обязательные поля не пропустят пустые значения, атрибут type проследит, чтобы вместо почты нам не прислали номер телефона, а по нажатию на кнопку валидная форма отправит все данные.
Но нам кроме всего этого хочется:
## Отправка без перезагрузки
Первым делом настроим отправку формы без перезагрузки страницы.
Перезагрузка страницы — это поведение по умолчанию для отправки формы. Чтобы его предотвратить, нам нужно «перехватить» управление в момент отправки и сказать форме, что делать вместо этого.
### Предотвращаем отправку данных
Для «предотвращения» срабатывания событий мы можем использовать метод preventDefault() на объекте события. В нашем случае событием будет отправка формы — submit.
Если наше событие находится в переменной event, то для предотвращения поведения по умолчанию мы можем вызвать event.preventDefault().
Чтобы «соединить» форму с нашей будущей собственной отправкой данных, мы напишем функцию, которая будет «слушать» событие отправки и реагировать на него.
Найдём форму на странице, с помощью getElementById и подпишемся на событие submit с помощью addEventListener. Пока мы не будем отправлять форму, а просто напечатаем в консоль строку «Отправка!» и убедимся, что механизм работает:
Мы можем просто передать функцию handleFormSubmit() как второй аргумент в addEventListener(), так как он автоматически передаст событие в качестве аргумента для handleFormSubmit().
Получится, что при отправке формы сработает событие submit, которое запустит наш обработчик handleFormSubmit().
В этот обработчик как аргумент event будет передано событие отправки. Мы вызовем event.preventDefault(), и форма не отправится самостоятельно.
### Собираем данные из формы
Следующий шаг — собрать всё, что необходимо отправить.
Нам не хочется собирать каждое значение отдельно.
Вместо этого мы будем использовать возможности языка, чтобы достать все поля и элементы управления из формы. Напишем функцию serializeForm:
Аргумент функции serializeForm — это элемент формы. Именно элемент — не селектор, а конкретный узел в DOM-дереве.
У форм есть свойство elements, которое содержит в себе все элементы управления и поля этой формы. Именно этим свойством мы воспользуемся, чтобы получить все данные из формы.
Если сейчас мы вызовем эту функцию, передав туда нашу форму как аргумент, то в консоли появится список всех элементов:
Обратите внимание, что тип этого набора элементов — HTMLFormControlsCollection. Это не массив и, чтобы пройтись циклом по списку элементов, нужно превратить его в массив с помощью вызова Array.from().
Нам останется собрать имя и значение каждого из полей. Для начала, выведем имя и значение каждого элемента в консоль:
Мы получили список элементов, преобразовали его в массив и прошлись по каждому элементу. У каждого элемента получили поля name и value и вывели их в консоль.
В консоли после запуска получим вывод по каждому из полей:
Заметим, что последняя строчка не имеет ни названия, ни значения. Это потому, что последний элемент, который мы проверяли — это кнопка.
Чтобы элементы без названия нам не мешались, мы отфильтруем наш набор. Воспользуемся методом filter, чтобы отбросить элементы с пустым именем. Также заменим метод forEach на map — он соберёт нам массив, который хранит объект с именем и значением каждого отфильтрованного элемента.
На выходе в консоли получится массив из объектов с name и value:
### Значения чекбоксов
Сейчас можно заметить, что nasa-experience имеет значение "1". Это неправильно:
Для этого мы можем использовать особое свойство checked, которое есть у чекбоксов.
const isOn = someCheckboxInput.checked isOn someCheckboxInput
Значение этого поля как раз булево, и мы можем использовать это в нашей функции serializeForm.
Но это свойство мы хотим использовать только на чекбоксе, а не на остальных полях. Это тоже можно сделать. Прочитаем тип элемента и, если он "checkbox", то возьмём в качестве значения поле checked:
Теперь значение поля nasa-experience будет true, если чекбокс отмечен, и false, если пропущен. Увидим такой вывод:
### Формат данных
В целом, нынешний формат данных в виде массива объектов нам может и подойти, но мы с вами используем кое-что лучше — FormData.
FormData — это особый тип данных, который можно использовать для отправки данных формы на сервер.
Мы воспользуемся им, чтобы сохранить данные из формы. Создадим экземпляр с помощью new FormData(), откажемся от массива со значениями и будем добавлять имена полей и их значения в FormData с помощью вызова функции append:
Но так как тип FormData специально создан для работы с формами, можно сделать гораздо проще 🙂
Стоит отметить, что nasa-experience в таком случае попадёт в финальные данные, только если чекбокс отметили. Если его не отметить, то в финальных данных он не окажется.
Когда чекбокс nasa-experience выделен, получим такой вывод:
Когда чекбокс не выделен — такой:
В первом случае чекбокс был отмечен, поэтому в списке есть элемент nasa-experience, во втором случае чекбокс был пропущен, поэтому такого элемента в списке данных нет.
Чтобы проверить, какие данные в себе содержит переменная типа FormData, можно использовать метод .entries(), он выведет список с данными, как в примере выше.
### Отправка на сервер
Теперь нам надо данные из формы отправить на сервер. Представим, что наш бэкенд предоставляет API-эндпоинт для сохранения данных. Попробуем отправить их.
Функция будет асинхронной, потому что работает с сетевыми запросами. В качестве аргумента она принимает FormData и отправляет запрос с помощью вызова fetch. Нам нужно указать правильный заголовок Content-Type у запроса, для формы он 'multipart/form-data':
Функция вернёт результат запроса к серверу, который мы сможем проверить на ошибки.
Теперь используем эту функцию в обработчике события отправки. Сериализуем форму и передадим её в функцию отправки. Вместо обращения напрямую к форме, будем читать её из объекта события. Форма в объекте события submit будет храниться в свойстве target:
Обратите внимание, что функция handleFromSubmit() стала асинхронной, так как она вызывает другую асинхронную функцию и дожидается её результата. Внутри response будет поле status, по которому мы сможем определить, успешно ли прошёл запрос и вывести соответствующее сообщение пользователю.
## Обработка загрузки и вывод сообщения о результате
Теперь немножко улучшим UX нашей формы. Сейчас она просто отправляет данные и ничего не сообщает пользователям. Это не круто, потому что отправителю будет непонятно, получилось ли записаться в «Mars Once» или нет.
Начнём с лоадера.
### Показываем лоадер во время отправки
Добавим его после кнопки и спрячем:
Прячем мы его, потому что хотим показать только во время запроса. Для этого напишем функцию, которая будет управлять его состоянием — делать лоадер видимым, если он не виден сейчас, и скрывать, если он виден. Так как технически это добавление и удаление класса hidden, то можно воспользоваться функцией toggle из classList API:
Вызовем эту функцию до отправки запроса, чтобы показать лоадер, и после запроса, чтобы скрыть. Лоадер будет виден до тех пор, пока запрос не завершится:
### Обрабатываем успешную отправку
Давайте теперь проверять ответ сервера. Допустим, нам хочется, чтобы при успешной отправке мы показывали alert() с сообщением об успешной отправке и прятали форму:
Мы должны вызвать onSuccess, только если форма была отправлена успешно. Для этого добавим проверку на статус ответа сервера — он должен быть 200 в случае успеха (статусы ответа разобраны в статье про HTTP протокол:
При успешной отправке покажется это сообщение, а форма пропадёт.
### Обрабатываем ошибки
Если что-то пошло не так, то мы хотим сказать пользователям об этом. Напишем функцию, которая будет вызывать alert() с сообщением, которое пришлёт сервер в случае ошибки:
Мы могли бы вызвать alert сразу на месте, но лучше вынести обработку ошибки в отдельную функцию. Так, если нам захочется добавить какие-то действия по обработке ошибок, нам будет проще ориентироваться в коде.
Вместе со статусом будем получать информацию об ошибке из поля error. Если запрос был успешным, то error будет пустым, но в случае ошибки там будет лежать сообщение:
Если что-то пошло не так, мы увидим причину. Форма останется на месте.
## Блокируем кнопку отправки на невалидной форме
Сейчас кнопку отправки можно нажать в любой момент, даже если форма невалидна. И хоть пользователь не сможет отправить форму из-за HTML-валидации, было бы неплохо предупредить, что кнопку нажимать пока рано.
Давайте будем её блокировать до тех пор, пока не будут заполнены все поля, которые требуется заполнить.
Напишем функцию, которая будет проверять валидность формы и блокировать кнопку, если требуется. Аргументом она будет принимать событие ввода с клавиатуры на полях ввода.
Так как событие ввода будет происходить на полях, а не на самой форме, то значение event.target — это поле. Чтобы получить форму, воспользуемся свойством form, значением которого является ссылка на родительскую форму.
Проверять валидность формы будем с помощью метода checkValidity() формы. Он запускает стандартные проверки. Результат проверки будем использовать, для того чтобы установить свойство disabled кнопки в значение true, если нужно заблокировать, и false, если кнопка должна быть доступна.
Теперь, пока форма не будет заполнена, кнопка будет заблокирована.
## Что у нас получилось
Мы сделали форму, которая отправляет данные без перезагрузки страницы, показывает сообщение об ошибке или успешной отправке и блокирует кнопку, пока не введены значения.
Для всего этого мы использовали методы HTML-элементов и элементов форм, которые нам предоставляет браузер и веб-платформа.
Конечно, этим работа с формами не заканчивается. Ещё можно сделать валидацию каждого поля в отдельности, загрузку картинок с возможностью их редактирования, добавить всякие комбо-боксы и нестандартные элементы.
Но для первой формы, с которой мы работали в JS, этого достаточно 🙂
В данной инструкции разберем как заменить стандартные формы в решении на формы CRM Битрикс24.
![](https://gvozdevsoft.ru/upload/medialibrary/f2a/f2a9061221ab092a4ffafe64988f1358.png)  
2\. Создаем новую форму либо выбираем из готовых. Кликаем по кнопке "Код на сайт".
![](https://gvozdevsoft.ru/upload/medialibrary/4d6/4d6a6b459aacb83958377918d84db3a6.png)  
3\. Переходим на вкладку "На внешнем сайте". Позже данный код нужно будет скопировать и разместить на сайте (шаг 8).
![](https://gvozdevsoft.ru/upload/medialibrary/57e/57e614f7d90d1d8477d26f031d933312.png)  
![](https://gvozdevsoft.ru/upload/medialibrary/097/0976bea3a3489e928052b42b9dd8ac87.png)  
· form\_calc\_index.php – Форма на главной странице калькулятора (для решений Стройка.GS, Ремонт.GS)
· form\_contacts.php – Форма на странице контактов
· form\_estimate.php – Форма на странице проектов (для решения Стройка.GS, Ремонт.GS, Profi.GS)
· form\_manager\_index.php – Форма на главной странице
· form\_measure.php – Форма вызова замерщика (для решений Стройка.GS, Ремонт.GS, Profi.GS)
· form\_popup\_callback.php – Всплывающая форма «Заказать звонок»
· form\_popup\_catalog.php – Всплывающая форма в каталоге «Заказть»
· form\_popup\_estimate.php – Всплывающая форма «Заказать расчет» на странице проектов (для решения Стройка.GS, Ремонт.GS, Profi.GS)
· form\_popup\_measure.php – Всплывающая форма вызова замерщика (для решений Стройка.GS, Ремонт.GS, Profi.GS)
· form\_popup\_request.php – Всплывающая форма в шапке сайта и в блоке преимуществ на главной странице «Оставить заявку»
· form\_service\_bottom.php – Форма (нижняя) на странице услуг
· form\_service\_top.php - Форма (верхняя) на странице услуг
· form\_slider\_main.php – Форма в слайдере на главной странице
5\. Для примера сделаем интеграцию формы Битрикс24 в файле form\_popup\_callback.php (popup - Заказать звонок).
![](https://gvozdevsoft.ru/upload/medialibrary/1a2/1a204ce3e28a78f2cc521665c076c977.png)  
Предварительно все формы решения можно заархивировать, чтобы была возможность вернуться к их использованию в будущем (шаг 12).
6\. Удаляем код в форме за исключением кода
Для форм с префиксом \_popup\_ необходимо также добавить класс class="form-hide"
![](https://gvozdevsoft.ru/upload/medialibrary/cbd/cbde9b654f7db0ba970e55ab190a1902.png)  
7\. В итоге файл должен иметь следующий вид.
![](https://gvozdevsoft.ru/upload/medialibrary/875/875f515f26e3a3feefe04130a1aad376.png)  
8\. Размещаем скопированный код формы из Битрикс24 (шаг 3).
![](https://gvozdevsoft.ru/upload/medialibrary/d44/d443538f83b1d5b11d2313e4e9050b8d.png)  
9\. Проверяем результат.
![](https://gvozdevsoft.ru/upload/medialibrary/74c/74c57a1064fbc73f31e225dd51d7a253.png)  
10\. Форма Битрикс24 размещена. В форме остались отступы от padding, которые при желании можно удалить.
![](https://gvozdevsoft.ru/upload/medialibrary/671/671f7d506d4e04b4e19d36c1940b9c0a.png)  
11\. Для удаления отступов padding необходимо внести небольшой css код в файл стилей customer.css
![](https://gvozdevsoft.ru/upload/medialibrary/83a/83a434c18ea4ab70ba62f1b9f3f4808d.png)  
12\. Старые формы решения можно предварительно заархивировать. Это даст возможность вернуться к старым формам решения в будущем.
![](https://gvozdevsoft.ru/upload/medialibrary/c14/c14dda985f491011544efa8d7ecc1398.png)  
Читайте также:  Статья 35. Градостроительные регламенты и параметры разрешённого использования земельных участков и объектов капитального строительства в общественно-деловых зонах

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *