Найти в Дзене
IT-информатор

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

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

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

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

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

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

Запрос/ответ
Запрос/ответ

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

Заметка: Для получения более полного представления о том, как работают клиент-серверные архитектуры, ознакомьтесь с модулем «Первые шаги в программировании на стороне сервера».

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

Элемент <form> определяет способ отправки данных. Все его атрибуты предназначены для того, чтобы вы могли настроить запрос на отправку, когда пользователь нажимает кнопку отправки. Двумя наиболее важными атрибутами являются  action  и method.

Атрибут action

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

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

<form action="http://foo.com">

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

<form action="/somewhere_else">

Если атрибуты не указаны, как показано ниже, данные из формы  <form> отправляются на ту же страницу, на которой размещается данная форма:

<form>

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

<form action="#">

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

Атрибут method

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

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

Метод GET

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

Рассмотрим следующую форму:

<form action="http://foo.com" method="get">

<div>

<label for="say">What greeting do you want to say?</label>

<input name="say" id="say" value="Hi">

</div>

<div>

<label for="to">Who do you want to say it to?</label>

<input name="to" id="to" value="Mom">

</div>

<div>

<button>Send my greetings</button>

</div>

</form>

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

-2

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

  • say, со значением Hi
  • to, со значением Mom

HTTP-запрос имеет следующий вид:

GET /?say=Hi&to=Mom HTTP/2.0

Host: foo.com

Заметка: Вы можете найти этот пример на GitHub — смотрите get-method.html (see it live also).

Метод POST

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

Давайте рассмотрим пример - это та же самая форма, которую мы рассматривали в разделе GET выше, но с атрибутом метода, установленным на POST.

<form action="http://foo.com" method="post">

<div>

<label for="say">What greeting do you want to say?</label>

<input name="say" id="say" value="Hi">

</div>

<div>

<label for="to">Who do you want to say it to?</label>

<input name="to" id="to" value="Mom">

</div>

<div>

<button>Send my greetings</button>

</div>

</form>

Когда форма отправляется с использованием метода 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 указывает тип ресурса, отправляемого на сервер. Мы обсудим эти заголовки позже.

Заметка: Вы можете найти эти примеры на GitHub — см. post-method.html (see it live also).

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

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

  1. Нажмите F12
  2. Выберите Network
  3. Выберите "All"
  4. Выберите "foo.com" во вкладке "Name"
  5. Выберите "Headers"

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

-3

Единственное, что отображается для пользователя, это URL-адрес. Как мы упоминали выше, с помощью запроса GET пользователь увидит данные в своей строке URL, но с запросом POST они не увидят. Это может быть очень важно по двум причинам:

  1. Если вам необходимо отправить пароль (или любой другой конфиденциальный фрагмент данных), никогда не используйте метод GET, иначе вы рискуете отобразить его в строке URL-адреса, что будет очень небезопасно.
  2. Если вам необходимо отправить большой объем данных, предпочтительнее использовать метод POST, поскольку некоторые браузеры ограничивают размеры URL-адресов. Кроме того, многие серверы ограничивают длину принимаемых ими URL.

На стороне сервера: получение данных

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

Пример: PHP

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

<?php

// The global $_POST variable allows you to access the data sent with the POST method by name

// To access the data sent with the GET method, you can use $_GET

$say = htmlspecialchars($_POST['say']);

$to = htmlspecialchars($_POST['to']);

echo $say, ' ', $to;

?>

В этом примере отображается страница с данными, которые мы отправили. Вы можете увидеть это в действии в нашем примере файла php-example.html, который содержит ту же форму примера, что и ранее, с методом POST и действием php-example.php. Когда он передается, он отправляет данные формы в php-example.php, который содержит код PHP, показанный в приведенном выше блоке. Когда этот код выполняется, выводится в браузере Hi Mom.

-4
Заметка: Этот пример не будет работать, когда вы загружаете его в браузер локально - браузеры не могут интерпретировать код PHP, поэтому при отправке формы браузер просто предложит загрузить файл PHP. Чтобы заставить его работать, вам нужно запустить пример через какой-нибудь PHP-сервер. Хорошие варианты для локального тестирования PHP - MAMP (Mac и Windows) и AMPPS (Mac, Windows, Linux).

Пример: Python

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

from flask import Flask, render_template, request

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])

def form():

return render_template('form.html')

@app.route('/hello', methods=['GET', 'POST'])

def hello():

return render_template('greeting.html', say=request.form['say'], to=request.form['to'])

if __name__ == "__main__":

app.run()

Два шаблона, упомянутые в приведенном выше коде, следующие:

  • form.html: та же форма, что мы видели выше в разделе метода POST, но с действием, установленным в {{ url_for ('hello') }}. (Это шаблон Jinja2, который в основном представляет собой HTML, но может содержать вызовы кода Python, на котором запущен веб-сервер, содержащийся в фигурных скобках. url_for ('hello') в основном говорит "перенаправить в / hello, когда форма отправлена" .)
  • greeting.html: Этот шаблон просто содержит строку, которая отображает два бита данных, передаваемых ему при визуализации. Это делается с помощью функции hello (), показанной выше, которая запускается при переходе по URL-адресу / hello.
Заметка: Опять же, этот код не будет работать, если вы просто попытаетесь загрузить его непосредственно в браузер. Python работает немного иначе, чем PHP - чтобы запустить этот код локально, вам нужно установить Python/PIP, а затем установить Flask с помощью pip3 install flask. На этом этапе вы сможете запустить пример, используя python3 python-example.py, а затем перейдите к localhost: 5000 в вашем браузере.

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

Существует много других серверных технологий, которые вы можете использовать для обработки форм, включая Perl, Java, .Net, Ruby и т. д. Просто выберите ту, которая вам больше нравится. Тем не менее, стоит отметить, что очень редко используются эти технологии напрямую, потому что это может быть сложно. Более распространенным является использование фреймворков, облегчающих обработку форм, таких как:

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

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

Специальный кейс: отправка файлов

Отправка файлов с HTML-формами является особым случаем. Файлы являются двоичными данными - или рассматриваются как таковые - тогда как все остальные данные являются текстовыми данными. Поскольку HTTP является текстовым протоколом, существуют особые требования для обработки двоичных данных.

Атрибут enctype

Этот атрибут позволяет указать значение HTTP-заголовка Content-Type, включенного в запрос, сгенерированный при отправке формы. Этот заголовок очень важен, потому что он сообщает серверу, какие данные отправляются. По умолчанию его значением является application / x-www-form-urlencoded. На человеческом языке это означает: «Это данные формы, которые были закодированы в параметры URL».

Если вы хотите отправить файлы, вам нужно сделать три шага:

  • Установите для атрибута метода значение POST, поскольку содержимое файла нельзя поместить в параметры URL.
  • Задайте значение enctype для multipart / form-data, потому что данные будут разбиты на несколько частей, по одной для каждого файла, плюс одна для текстовых данных, включенных в тело формы (если текст также вводится в форму).
  • Включите один или несколько виджетов выбора файлов, чтобы пользователи могли выбирать файлы, которые будут загружены.

Пример:

<form method="post" enctype="multipart/form-data">

<div>

<label for="file">Choose a file</label>

<input type="file" id="file" name="myFile">

</div>

<div>

<button>Send the file</button>

</div>

</form>

Заметка: Некоторые браузеры поддерживают атрибут множественного элемента <input>, что позволяет выбирать более одного файла для загрузки только с одним элементом <input>. То, как сервер обрабатывает эти файлы, зависит от технологии, используемой на сервере. Как упоминалось ранее, использование фреймворка значительно облегчит вашу жизнь.

ВНИМАНИЕ!
Многие серверы настроены на ограничение размера файлов и HTTP-запросов, чтобы предотвратить злоупотребления. Важно проверить этот лимит у администратора сервера перед отправкой файла.

Проблемы безопасности

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

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

XSS и CSRF

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

XSS позволяет злоумышленникам внедрить клиентский скрипт в веб-страницы, просматриваемые другими пользователями. Уязвимость межсайтовых скриптов может использоваться злоумышленниками для обхода средств контроля доступа, таких как одна и та же политика происхождения. Эффект этих атак может варьироваться от мелких неприятностей до значительного риска для безопасности.

CSRF-атаки аналогичны XSS-атакам в том, что они начинаются одинаково - с внедрения клиентского скрипта в веб-страницы - но их цель иная. Злоумышленники CSRF пытаются передать привилегии пользователям с более высокими привилегиями (например, администратору сайта), чтобы выполнить действие, которое они не должны выполнять (например, отправлять данные ненадежному пользователю).

Чтобы предотвратить эти атаки, вы всегда должны проверять данные, которые пользователь отправляет на ваш сервер, и (если вам нужно их отображать) стараться не отображать HTML-контент, предоставленный пользователем. Вместо этого вы должны обработать предоставленные пользователем данные, чтобы не отображать их дословно. Почти все платформы на рынке сегодня реализуют минимальный фильтр, который удаляет элементы HTML <script>, <iframe> и <object> из данных, отправленных любым пользователем. Это помогает снизить риск.

Ссылка на источник: MDN

Поделись этой статьей в соц. сетях, это поможет развитию канала
Подписывайся.
Ставь лайк.