Поля ввода

polya vvoda Сценарии на стороне сервера

Управляющие элементы ввода определяются вложенными тегами <input>. В данном примере теги ввода обладают двумя ключевыми параметрами. Параметр type в текстовых полях ввода принимает значение text, а в кнопках отправки формы (которые отправляют данные серверу и по умолчанию имеют метку «Submit Query») — значение submit. Параметр name служит для идентификации введенного значения по имени, когда данные формы будут получены сервером. Например, серверный сценарий CGI, который мы увидим чуть ниже, использует строку user как ключ к получению данных, введенных в текстовое поле этой формы.

Как будет показано в последующих примерах, другие параметры тега <input> могут определять начальные значения (value=X), режим «только для чтения» (readonly) и так далее. Также ниже мы увидим, что параметр type может принимать другие значения — для передачи скрытых данных (type=hidden), повторной инициализации полей (type=reset) или создания кнопки для выбора нескольких вариантов (type=checkbox).

Ме тод от прав ки: get и post

Формы имеют также параметр method, определяющий стиль кодирования, используемый при передаче данных через сокет на целевой сервер. В данном случае используется стиль post, при котором устанавливается связь с сервером, а затем ему в отдельной передаче посылается поток данных, введенных пользователем.

Другим возможным вариантом является стиль get, при котором входная информация передается серверу за один шаг путем добавления данных пользователя в конец адреса URL, вызывающего сценарий, обычно после символа ?. Параметры запроса были уже представлены выше, когда мы знакомились с адресами URL, — мы еще будем использовать их далее в этом разделе.

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

Метод get обычно считается более эффективным, но он ограничивается конечной длиной строки запроса в операционной системе и менее безопасен (параметры могут сохраняться в файлах журналов на сервере, например). Метод post позволяет обрабатывать большие объемы входных данных и в некоторых случаях обеспечивает более высокий уровень безопасности данных, но он требует выполнить дополнительную передачу. К счастью, модуль Python cgi прозрачным образом обрабатывает оба стиля кодирования данных, поэтому нашим сценариям CGI не приходится беспокоиться о том, который из стилей использован.

Обратите внимание, что для иллюстрации адрес URL в параметре action в данном примере записан в виде полного адреса. Так как броузер помнит, откуда пришла страница HTML, содержащая адрес URL, он будет действовать так же, если указать лишь имя файла сценария, как показано в примере 15.7.

Пример 15.7. PP4E\Internet\Web\tutor3-minimal.html

<html>

<title>CGI 101</title>

<body>

<H1>A first user interaction: forms</H1>

<hr>

<form method=POST action="cgi-bin/tutor3.py">

<P><B>Enter your name:</B>

<P><input type=text name=user>

<P><input type=submit>

</form>

</body></html>

Полезно помнить, что адреса URL, указываемые в параметре action тегов форм и в гиперссылках, служат адресами в первую очередь для броузера, а не для сценария. Сам сценарий tutor3.py безразличен к тому, какого вида URL его запустил — минимальный или полный. На самом деле все части URL, включая имя файла сценария (и вплоть до параметров запроса URL) участвуют в диалоге между броузером и HTTP-сервером до того, как будет запущен сценарий CGI.

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

Сценарий, возвращающий ответ

Пока мы создали только одну статическую страницу с полем ввода. Но кнопка отправки на этой странице творит чудеса. При нажатии на нее запускается удаленная программа, адрес URL которой указан в параметре action формы, и этой программе передаются данные, введенные пользователем, в соответствии с параметром method формы, определяющим стиль кодирования. Пока пользователь на клиентской машине ждет ответа, на сервере запускается сценарий Python, представленный в примере 15.8, который обрабатывает данные, введенные в форму.

Пример 15.8. PP4E\Internet\Web\cgi-bin\tutor3.py

#!/usr/bin/python """

выполняется на стороне сервера, читает данные формы, выводит разметку HTML;

url=http://servername/cgibin/tutor3.py

import cgi

form = cgi.FieldStorage() # извлечь данные из формы

print(‘Content-type: text/html’) # плюс пустая строка

html = """

<TITLE>tutor3.py</TITLE>

<H1>Greetings</H1>

<HR>

<P>%s</P>

<HR>"""

if not ‘user’ in form:

print(html % ‘Who are you?’) else:

print(html % (‘Hello, %s.’ % form[‘user’].value))

Как и прежде, этот CGI-сценарий на языке Python выводит разметку HTML, воспроизводящую страницу ответа в броузере клиента. Но этот сценарий делает еще кое-что: он использует стандартный модуль cgi для извлечения данных, введенных пользователем на предыдущей вебстранице (см. рис. 15.6).

К счастью, в Python это происходит автоматически: обращение к конструктору класса FieldStorage модуля cgi автоматически выполняет всю работу по извлечению данных формы из входного потока и переменных окружения независимо от способа передачи этих данных — в виде потока в стиле post или в виде параметров, добавляемых в URL в стиле get.

Вводимые данные, пересылаемые в любом из стилей, выглядят для сценариев Python одинаково.

Сценарии должны вызвать конструктор cgi.FieldStoreage только один раз, перед обращением к значениям полей. В результате этого вызова возвращается объект, имеющий вид словаря, — поля для ввода данных пользователем из формы (или параметры из адреса URL) представляются в виде значений ключей этого объекта. Например, form[‘user’] в сценарии является объектом, атрибут value которого представляет собой строку, содержащую текст, введенный в текстовое поле формы. Если вы перелистаете книгу назад, к примеру с разметкой HTML страницы формы, то заметите, что параметр name поля ввода имел значение user — имя в форме HTML стало ключом, по которому введенное значение извлекается из словаря. Объект, возвращаемый конструктором FieldStorage, поддерживает и другие операции со словарями, например с помощью метода in можно проверить, есть ли некоторое поле во входных данных. Перед завершением этот сценарий выводит разметку HTML, создающую страницу результата, на которой повторяются данные, введенные пользователем в форму. Два выражения форматирования строк (%) применяются для вставки введенного текста в строку ответа, а эта строка ответа — в заключенный в тройные кавычки блок строк HTML. Вывод сценария выглядит так:

<TITLE>tutor3.py</TITLE>

<H1>Greetings</H1>

<HR>

<P>Hello, King Arthur.</P>

<HR>

В броузере этот вывод превращается в страницу, изображенную на рис. 15.7.

Рис. 15.7. Результат обработки параметров формы сценарием tutor3.py

Передача параметров в адресах URL

Обратите внимание, что вверху броузера отображается адрес URL сценария, сгенерировавшего эту страницу. Сам адрес URL мы не вводили — он появился из атрибута action тега <form> в разметке HTML предыдущей страницы. Однако ничто не мешает ввести адрес URL сценария вручную в адресную строку броузера, чтобы запустить сценарий, как мы это делали ранее, в примерах сценария CGI и файла HTML.

Но здесь есть одна ловушка: откуда возьмется значение поля ввода, если страницы с формой нет? То есть если ввести адрес URL сценария CGI самостоятельно, как будет заполнено поле ввода? Ранее, говоря о форматах адресов URL, я упомянул, что в схеме кодирования get входные параметры помещаются в конец URL. При явном вводе адресов сценариев тоже можно добавлять входные значения в конец URL, где они служат той же цели, что и поля <input> в формах. Кроме того, модуль Python cgi обеспечивает одинаковое представление в сценариях данных, полученных из адресов URL и форм.

Например, можно вообще пропустить заполнение страницы с формой и прямо вызвать сценарий tutor3.py, обратившись к URL вида (введя его вручную в адресной строке броузера):

http://localhost/cgibin/tutor3.py?user=Brian

В этом адресе URL значение поля ввода с именем user задано явно, как если бы пользователь заполнил форму ввода. При вызове подобным образом единственным ограничением является соответствие имени параметра user имени, ожидаемому сценарием (и жестко определенному в разметке HTML формы). Мы используем здесь лишь один параметр, но в целом перечень параметров URL обычно предваряется символом ?, за которым следует одно или более присваиваний вида name=value, разделяемых символами &, если их больше одного. На рис. 15.8 представлена страница ответа, получаемая после ввода URL с явно указанными данными.

Фактически формы HTML, определяющие стиль кодирования get, тоже вызывают добавление входных параметров в адреса URL подобным образом. Попробуйте изменить пример 15.6 так, чтобы он использовал параметр method=GET, и отправьте форму — содержимое поля ввода имени из формы появится в адресе страницы ответа в виде параметра запроса, как и в адресе URL, который был введен вручную на рис. 15.8. Формы могут использовать любой стиль, post или get. При вводе адресов URL вручную можно использовать только метод get.

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

Рис. 15.8. Результат обработки параметров URL сценарием tutor3.py

 

Нетрудно заметить сходство между приведенными вызовами сценариев CGI с передачей им явно входных параметров и функ циями, использующимися удаленно в Сети. Передача данных сценариям через URL аналогична передаче именованных аргументов функциям Python как по действию, так и синтаксически. На самом деле некоторые продвинутые веб-фреймворки, такие как Zope, делают связь между адресами URL и вызовами функций в Python еще более явной (адреса URL более тесно связаны с вызовами функций Python).

Между прочим, если очистить поле ввода имени на форме ввода (то есть сделать его пустым) и нажать кнопку отправки, то поле user с именем окажется пустым. Точнее, броузер может вообще не послать это поле вместе с другими данными формы, несмотря на то, что оно присутствует в разметке HTML, описывающей структуру формы. Сценарий CGI обнаруживает такое отсутствующее поле с помощью метода in словаря и порождает в ответ страницу, изображенную на рис. 15.9.

Рис. 15.9. Пустое поле с именем порождает страницу сообщения об ошибке

Вообще говоря, сценарии CGI должны проверять отсутствие каких-либо полей, поскольку пользователь мог не ввести их в форму или формы вообще нет, — поля ввода могут быть не добавлены в конец явно введенного адреса URL. Например, если ввести URL сценария вообще без параметров — то есть отбросить текст, начиная с ?, и оставить только адрес http://localhost/cgi-bin/tutor3.py — будет получена та же самая страница ответа с сообщением об ошибке. Так как любой сценарий CGI может быть вызван через форму или через URL, сценарии должны быть готовы к обеим ситуациям.

Использованная литература:

Марк Лутц — Программирование на Python, 4-е издание, II том, 2011

Каталог сайтов Всего.ру
Оцените статью
Секреты программирования
Добавить комментарий