Одним из средств, которые позволяют осуществить взаимодействие между клиенской и серверной
частями приложения, является интерфейс CGI (Common Gateway Interface – общий шлюзовый
интерфейс), имеющий реализации как для Windows-ориентированных программ, так и для приложений,
функционирующих в среде Unix. Этот интерфейс разработан так, чтобы для создания серверного
приложения можно было использовать любой язык программирования, который может работать со
стандартными устройствами ввода/вывода. Серверная часть приложения, которая обрабатывает данные
клиента, полученные с использованием CGI-интерфейса, называется CGI-приложением.
При использовании CGI-приложений информация на Web-странице клиента,
предназначенная для передачи на сервер, предствляется в виде HTML-форм.
Итерфейс CGI вместе с HTML-формой были разработаны в 1991 Марком
Андерссеном и Эриком Бином в национальном центре суперкомпьютерных приложений NCSA
(Center for Supercomputing Applications) при университете штата Иллинойс (США) в ходе работы над
браузером NCSA Mosaic, первым браузером под операционную систему Microsoft Windows. На основе его
исходного кода были разработаны браузеры Netscape Navigator и Micosoft Internet Explorer.
При передаче данных формы на сервер с использованием CGI-интерфейса с помощью атрибутов
method и enctype тега <form> могут быть
указаны метод передачи и MIME-тип данных. Первый тип данных (url-кодированные) задается по умолчанию и используется при передаче любых
данных формы (за исключением файлов). Второй тип может быть указан только для метода POST, задает
структуру данных, имеющую несколько частей, и используется при передаче файлов из формы на сервер.
MIME (Multipurpose Internet Mail Extensions
– многоцелевые расширения почты Internet, произносится как <майм>) – первоначально
стандарт, описывающий передачу различных типов данных по электронной почте. Сейчас –
спецификация для кодирования информации и форматирования сообщений таким образом, чтобы их можно
было пересылать по сети Internet.
Формат MIME поддерживает передачу нескольких блоков данных в пределах одного
сообщения. Причем блоки могут передаваться не только в виде одноуровневой последовательности, но в
виде иерархии с вложением элементов друг в друга.
Для обозначения множественного содержимого используются типы
multipart/*. Работа с такими типами осуществляется по правилам, описанным
в RFC 2046.
Для передачи множественного сообщения в заголовок Content-Type
добавляется атрибут boundary (граница), который обозначает последовательность символов,
разделяющих части сообщения. Граница может состоять из цифр, букв и символов <'()+_,-./:=?>. При
использовании специальных символов (не цифр и букв) значение параметра boundary следует заключать в
двойные кавычки. Максимальная длина границы – 70 символов.
Для формы допускается использовать следующие два MIME-типа данных:
Если MIME-тип не указан (что является типичным) или указан тип
имя=значение&имя=значение&имя=значение& . . .
При этом используется url-кодирование передаваемых имен и значений, которое заключается в следующем:
При разработке приложения в рамках технологии "клиент-сервер" необходимо выбрать Web-сервер и
осуществить его конфигурирование. В примерах, приведенных в описании данной лабораторной работы,
предполагается использование сервера Apache. Он является кросс-платформенным и нашел широкое
применение у разработчиков клиент-серверных приложений. Однако для выполнения данной работы можно
выбрать любой из доступных Web-серверов.
Конфигурирование сервера Apache осуществляется путем задания
необходимых значений директивам, содержавшимся в его файле конфигурации
httpd.conf. Поскольку этот файл содержит довольно много директив,
приведем лишь некоторые из них, имеющих прямое отношение к выполняемой работе (в скобках указано
заданное значение директивы):
Остальные директивы файла конфигурации httpd.conf необходимо
просмотреть (все они имеют комментарии) и при необходимости изменить их начальные значения.
При всяком изменении значений конфигурационного файла необходимо
осуществлять перезапуск Web-сервера.
Если серверное приложение задается не в виде
exe-файла, а является программой, написанной на языке Python и заданной
в виде файла с расширением .py, то необходимо дополнительно выполнить
следующие изменения в конфигурационном файле Apache:
Коды статуса (Status) используются в http-протоколе для передачи сервером браузеру статуса запроса. Поле статуса заголовка содержит три цифры, за которыми следует строка текста, поясняющая код. Коды статуса сгруппированы по первой цифре:
Полный список кодов статуса можно найти по адресу:
http://www.w3.org/hypertext/WWW/Protocols/HTTP/HTRESP.html.
Клиентская часть приложения содержит HTML-документ, реализованный в виде примера
№1, содержащего форму (тег <form>), с помощью
которого осуществляется прием данных от клиента и передача с использованием интерфейса CGI
(см. раздел 1) запроса для обработки серверной программе
cgi_parse_form.py.
HTML-форма примера №1 имеет поля,
предоставляющие пользователю такие возможности:
Свойства элементов формы (цвет и размер символов, выравнивание текста, цвет фона и др.)
заданы с помощью файла lab.css, который подключается к HTML-документу
примера №1 и содержит следующие CSS:
body {
margin:1.5cm 1.5cm 2.0cm 2.5cm;
font-size:5.5mm;
color:#000080;
background-color:#eeeeee;
}
h1 {
text-align:center;
color:#d0d;
text-transform:uppercase;
font:italic 0.25in tahoma;
}
input, textarea, option, button {
background:#eeffee;
color:#005000;
font-size:6mm;
border:outset 2px black;
}
td {
vertical-align:middle;
}
Пример №1
<!DOCTYPE html>
<html>
<head>
<title>Обработка данных формы</title>
<link rel="stylesheet" href="lab.css">
</head>
<body>
<h1>Обработка данных формы</h1>
<form method="get" action="http://zykov/PYTHON/cgi_parse_form.py">
<table align="center" width="50%" style="color:#000080;font-size:6mm">
<tr> <td> Введите имя
<td><input type="text" size="10" class="form" name="name"
<tr><td cols="2">
<span style="margin-left:2cm; outline:1px solid blue;font-size:5.5mm">
Отметьте то, что хотите получить
</span>
<tr><td>Данные HTML-формы
<td><input type="checkbox" name="check1" value="data">
<tr><td>Переменные окружения
<td><input type="checkbox" name="check2">
<tr><td>Рисунки<td><input type=checkbox name="check3" value="img">
<tr> <td>Примеры формирования
<td><select name="help" size="3" multiple class="form">
<option value="str"> строки
<option value="list"> списка
<option value="tuple"> кортежа
<option value="set"> множества
<option value="dict"> словаря
</select>
<tr> <td>
<input type="reset" value="Сброс" class="kn">
<input type="submit" value="Передача" class="kn">
</table><br>
</form>
</body>
</html>
CGI скриптом будем называть программу (скрипт), которая выполняется на стороне сервера и
использует интерфейс CGI (см. раздел 1) для взаимодействия с клиетнтской
частью.
Программа на языке Python, выполняемая на Web-сервере, имеет два
основных отличия от программ, выполняемым на стороне клиента:
Первая строка программы начинается с двух символов #!, которые иногда
(в том числе в документации языка Python) называются shebang, после
которых указывается путь к интерпретатору языка Python
(#!c:/ . . . /Python/Python35-32/python.exe), что позволяет серверу
вызвать интерпретатор для обработки скрипта. Отметим, что слово shebang,
по одной из версий, образовано названиями этих двух начальных символов –
sh[arp]+bang (bang – одно из названий
восклицательного знака).
Затем указывается заголовок http протокола,
который отделяется от его тела пустой строкой, реализованной функцией
print(). В http-заголовке задан параметр,
который указывает, как данные, переданные сервером, будут интерпретироваться браузером на стороне
клиента. В данном случае будет сформирована Web-страница. Если для параметра
Content-Type будет задано значение text/plain,
то браузер воспримет данные, переданные сервером, как простой текст и в случае передачи
HTML-документа выведет на экран его содержимое (подобно режиму "Просмотр HTML-кода").
Необходимо отметить, что http-заголовок с
параметром Content-Type применим в серверных приложениях, использующих
интерфейс CGI. В сдучае использования для обмена данными с клиентом технологии AJAX
(см. раздел 1 лаб. раб. №10) этот http
-заголовок применять не следует.
Имеется несколько способов получения доступа к данным HTML-формы,
переданным на сервер. В данной лабораторной работе выбран способ, основанный на использовании
метода parse() модуля cgi (см. подраздел 3.3). Для реализации этого способа
к серверной программе необходимо подключить следующие модули языка Python:
Модуль cgitb (cgi traceback – cgi отладчик) предназначен для
формирования в случае возникновения исключения при работе CGI скрипта отладочной информации,
содержащей фрагмент кода программы, в котором отмечена строка с ошибкой, описание исключения и
некоторые другие данные, например, путь к выполняемой программе.
Формат и способы предоставления этих данных пользователю или
администратору задаются c помощью метода
enable([display[,logdir[,context[,format]]]]) при
инициализации модуля. Все параметры метода являются необязательными и задают следующее:
Модуль cgitb нашел применение в серверной программе
cgi_parse_form.py во время ее отладки. При его инициализации:
cgitb.enable(logdir=
"D:/ . . . Apache Group/Apache/root/Python/TMP/", context=7)
были указаны: путь к каталогу, содержащему отладочную информацию (logdir),
и размер фрагмента программы (число строк), содержащего ошибку (context).
Значения остальных параметров заданы по умолчанию.
Модуль cgi имеет следующие методы, которые могут быть искользованы при разработке CGI скриптов:
Shell Environment:
COMSPEC C:\Windows\system32\cmd.exe
DOCUMENT_ROOT d:/disk_f/disk_d/program files/apache group/apache/root
GATEWAY_INTERFACE CGI/1.1
HTTP_ACCEPT text/html, application/xhtml+xml, */*
HTTP_ACCEPT_ENCODING gzip, deflate
HTTP_ACCEPT_LANGUAGE ru-RU
HTTP_CONNECTION Keep-Alive
HTTP_DNT 1
HTTP_HOST zykov
HTTP_USER_AGENT Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko
PATH C:\Program Files\NVIDIA Corporation\PhysX\Common;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;
C:\Windows\System32\WindowsPowerShell\v1.0\;C:\FPC\2.6.0\bin\i386-Win32;
C:\Program Files\Microsoft SQL Server\100\Tools\Binn\;
C:\Program Files\Microsoft SQL Server\100\DTS\Binn\;
C:\Program Files\Autodesk\Backburner\;C:\Program Files\TortoiseSVN\bin
QUERY_STRING name=%FB%FB&check2=on
REMOTE_ADDR 172.17.72.142
REMOTE_PORT 1899
REQUEST_METHOD GET
REQUEST_URI /PYTHON/work_form.py?name=%FB%FB&check2=on
SCRIPT_FILENAME d:/disk_f/disk_d/program files/apache group/apache/root/python/work_form.py
SCRIPT_NAME /PYTHON/work_form.py
SERVER_ADDR 172.17.72.142
SERVER_ADMIN admin@purple.ntu
SERVER_NAME zykov
SERVER_PORT 80
SERVER_PROTOCOL HTTP/1.1
SERVER_SIGNATURE <:ADDRESS>Apache/1.3.31 Server at zykov Port 80</ADDRESS>
SERVER_SOFTWARE Apache/1.3.31 (Win32)
SYSTEMROOT C:\Windows WINDIR C:\Windows;
Current Working Directory:
d:\disk_f\disk_d\program files\apache group\apache\root\python;
These environment variables could have been set:
AUTH_TYPE
CONTENT_LENGTH
CONTENT_TYPE
DATE_GMT
DATE_LOCAL
DOCUMENT_NAME
DOCUMENT_ROOT
DOCUMENT_URI
GATEWAY_INTERFACE
LAST_MODIFIED
PATH
PATH_INFO
PATH_TRANSLATED
QUERY_STRING
REMOTE_ADDR
REMOTE_HOST
REMOTE_IDENT
REMOTE_USER
REQUEST_METHOD
SCRIPT_NAME
SERVER_NAME
SERVER_PORT
SERVER_PROTOCOL
SERVER_ROOT
SERVER_SOFTWARE
In addition, HTTP headers sent by the server may be passed in the environment as well. Here are
some common variable names:
HTTP_ACCEPT
HTTP_CONNECTION
HTTP_HOST
HTTP_PRAGMA
HTTP_REFERER
HTTP_USER_AGENT;
Для получения доступа к данным, переданным браузером из HTML-формы клиента серверу, можно
воспользоваться методом parse() модуля cgi,
все параметры которого имеют значения, заданные по умолчанию. Для параметра
keep_blank_values такое значение равно 0, что означает, что незаполненные
поля HTML-формы сервером не будут обрабатываться (см. подраздел 3.2).
Поскольку предполагается, что пользователь в поле ввода имени свое имя
может не указывать, то для обработки этого поля в любом варианте (заполненном и незаполненном),
необходимо при вызове метода parse() явно задать значение параметра
keep_blank_values (остальные параметры имеют значения, заданные по
умолчанию):
form=cgi.parse(keep_blank_values=1)
Этот метод возвращает данные HTML-формы, полученные сервером, в виде
словаря form, ключами которого являются имена полей формы (заданные
атрибутами name), а значения полей формы представлены в виде списков.
Причем поля HTML-формы, заданные тегом <input>, которые имеют одиночные
значения, являются одноэлемнтными списками, поля, которые могут иметь множественное значение
(например, тег <select> с атрибутом
multiple), являются списками с несколькими элементами.
Поэтому доступ к значениям полей HTML-формы можно получить следующим
образом:
Серверная программа после приема и обработки данных формирует ответ в виде HTML-документа, который отсылается клиенту и воспроизводится браузером на стороне клиента в виде Web-страницы. Для упрощения форматирования текста были разработаны следующие форматы представления данных в виде констант языка Python:
Формат "H" заголовка
Формат "H2" заголовка
Формат текстовых данных
Поскольку эти константы могут быть использованы разными программами при форматировании данных,
отсылаемых клиенту, они помещены в модуль my_mod, который реализован в
виде файла my_mod.py.
В качестве примера использования метода
parse() модуля cgi для доступа к данным
HTML-формы рассмотрим приложение, клиенткая часть которого реализована в виде
примера №1, а серверная – в виде CGI скрипта
cgi_parse_form.py:
#!c:/ . . . /Python/Python35-32/python.exe
print
(
"Content-Type: text/html"
)
print
()
import
cgi, cgitb
from
os
import
environ
as
env
from
my_mod
import
*
HELP={
'str'
:
'строки: s=\'Python\''
,
'list'
:
'списка: a_list=[255,"web",1.33,True]'
,
'tuple'
:
'кортежа: a_tuple=(\'name\',100)'
,
'set'
:
'множества: a_set={1,2,\'a\',\'b\'}'
,
'dict'
:
'словаря: a_dict={\'name\':\'Bob\',\'sport\':\'football\'}'
}
cgitb.enable(logdir=
"D:/ . . . Apache Group/Apache/root/Python/TMP/", context=7)
form=cgi.parse(keep_blank_values=1)
name=
'клиент'
if
form[
'name'
][0]: name=form[
'name'
][0]
print
(H2,
"Ув. "
,name,
"!"
, sep=
""
)
if
"check1"
in
form
or
"check2"
in
form
or
"check3"
in
form
or
"help"
in
form:
print
(
'Вам предоставляются:'
)
if
'check1'
in
form:
print
(H,
"Данные HTML-формы:"
)
print
(D, form)
if
'check2'
in
form:
print
(H,
"Переменные окружения:"
)
print
(D,
'REQUEST_METHOD= '
, env[
'REQUEST_METHOD'
])
print
(D,
'QUERY_STRING= '
, env[
'QUERY_STRING'
])
print
(D,
'HTTP_USER_AGENT= '
, env[
'HTTP_USER_AGENT'
])
if
'check3'
in
form:
print
(H,
"Рисунки:"
)
print
(H,
"<img src='everest.jpg'>"
)
print
(H,
"<img src='flower.jpg'>"
)
if
'help'
in
form:
print
(H,
"Примеры создания:"
)
for
el
in
form[
'help'
]:
print
(D, HELP[el])
else
:
print
(
'Вы действительно ничего не хотите заказать?'
),
которая выполняет следующие действия:
"Ув. Smith T.! Вам предоставляются: "
и передает требуемые данные;Данные HTML-формы:
{'name': [''], 'check2': ['on'], 'check3': ['img'], 'help': ['str', 'list', 'set', 'dict'], 'check1': ['data']}
из которого следует, что в HTML-форме клиента не было заполнено только два поля: "name" тега <input> и "tuple" тега <select> (см. раздел 2 );Переменные окружения:
REQUEST_METHOD= GET
QUERY_STRING= name=Smith+T.&check1=request&check2=on&check3=img
HTTP_USER_AGENT= Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko;
Значения переменных окружения были получены с помощью свойства environ модуля os, в котором содержатся значения переменных окружения в виде пар "имя:значение". Например, значение QUERY_STRING может быть определено и передано следующим образом:Примеры формирования данных
Списки: a_list=[255,"web",1.33,True]
Словари: a_dict={{'name':'Ronaldo','sport':'football'}
"Ув. клиент! Вы действительно ничего не хотите заказать?"
Результаты работы программы cgi_parse_form.py, полученные при использовании браузеров Internet Explorer, Chrome, Firefox, Opera и Safari, показывают, что она правильно обрабатывает различные поля HTML-формы как с использованием латинских букв, так и при использовании кириллицы. Поэтому способ доступа к данным, переданным клиентом серверу, основанный на использовании метода cgi.parse(), является основным и будет в дальнейшем исиользоваться как при обработке данных HTML-формы (см. пример №1), так и при передаче данных клиента с использованием технологии AJAX (см. пример №1 лаб. раб. №10).
Разработать приложение на базе технологии "клиент-сервер". При этом клиентская часть передает
на сервер имя пользоватекля и номера функций, а серверная часть, написанная на языке Python,
выполняет эти функции и возвращает пользователю результат.
В задачи клиентской части входит: разработать HTML-документ,
содержащий форму, обязательными элементами которой являются:
Функции по группам делятся следующим образом:
В задачи серверной части входит:
Номер п/п | Теги | Случайные числа | Функции | |||
---|---|---|---|---|---|---|
Диапазон | Количество | Группа 1 | Группа 2 | Группа 3 | ||
1 | input | (-5, 5) | 10 | а) | а) | а) |
2 | select | (-7, 21) | 20 | б) | б) | б) |
3 | input | (-20, 5) | 7 | в) | в) | а) |
4 | select | (-25, 40) | 22 | г) | а) | б) |
5 | input | (-7, 12) | 8 | д) | б) | а) |
6 | select | (-22, 15) | 21 | а) | в) | б) |
7 | input | (-12, 31) | 40 | б) | а) | а) |
8 | select | (-14, 8) | 8 | в) | б) | б) |
9 | input | (-13, 20) | 50 | г) | в) | а) |
10 | select | (-4, 3) | 12 | д) | а) | б) |
11 | input | (-33, 44) | 16 | а) | б) | а) |
12 | select | (-55, 66) | 33 | б) | в) | б) |
13 | input | (-7, 5) | 14 | в) | а) | а) |
14 | select | (-19, 28) | 50 | г) | б) | б) |
15 | input | (-8, 5) | 7 | д) | в) | а) |
16 | select | (-24, 26) | 36 | а) | а) | б) |
17 | input | (-11, 9) | 19 | б) | б) | а) |
18 | select | (-9, 3) | 13 | в) | в) | б) |
19 | input | (-17, 42) | 39 | г) | а) | а) |
20 | select | (-3, 3) | 11 | д) | б) | б) |