В прошлой записи Мы c Вами бахнули сервер. Сейчас его нужно запустить, ибо нижеприведённые примеры не будут работать без него.
В этом раз Мы поговорим о том, как можно несколько облагородить сервер и сделать его более удобным для клиентов.
Первый инструмент, который Мы разберём - это CGI-скрипты. CGI-программа - универсальный инструмент, который запускается сервером в качестве дочернего процесса и служит обработчиком информации, полученной от клиента.
CGI.
Первое, что Нам пригодится, это HTML-страница. Для того, чтобы осознать всю мощь класса FieldStorage(), с которым Мы, кстати, уже сталкивались в прошлой записи, натолкаем в эту страницу побольше различных полей:
| HTML5 | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| <!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>CGI</title>
</head>
<body>
<p>Hello,<p>
<form method=POST action="http://localhost/cgi-bin/cgi1.py">
Enter your name<br>
<input type=text name=user><br><br>
What is your sex?<br>
<input type=radio name=sex value=male>
Male<br>
<input type=radio name=sex value=female>
Female<br><br>
Which music do you love?<br>
<input type=checkbox name=mus value=Dnb>
Drum and Bass<br>
<input type=checkbox name=mus value=Dubstep>
Dubstep<br>
<input type=checkbox name=mus value=Club>
Club<br>
<input type=submit value="Отправить">
</form>
</body>
</html> |
|
В этом HTML-документе используется три типа полей:- text - поле для ввода текста
- radio - радиокнопки(переключатель)
- checkbox - флажки.
Не забывайте, что адрес, указанный в параметре action, должен совпадать с адресом CGI-скрипта, который Вы хотите применить к этой форме. Более того, адрес скрипта должен содержать в себе только ASCII символы. Обратите внимание на то, что радиокнопки имеют одинаковые имена(атрибут name). Если кнопкам не присвоить имена или присвоить, но разные, они начнут независимое друг от друга существование. Нам же нужен полноценный переключатель.
А вот и сам CGI-скрипт:
| Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| import cgi
form=cgi.FieldStorage()
flist=''
if type(form['mus'])==list:
for i in form['mus']:
flist+=i.value+' '
else:
flist=form['mus'].value
print('Content-type: text/html\n')
print('<title>answear</title>')
print("""<p>%s, We found composition in %s style which is popular in %s
companies.</p>""" %(form['user'].value, flist, form['sex'].value)) |
|
Как видите, одна только form вместила в себя всю информацию, введённую в поля. Для того, чтобы извлечь данные, Мы вводим имя нужной Нам формы(в квадратных скобках) и обращаемся к атрибуту value. Думаю, Вы заметили блок if-else в начале скрипта. Дело в том, что при множественном выборе, что в, общем-то, свойственно флажкам, form извлечёт список. Причём список этот будет содержать в себе объекты MiniFieldStorage(). Поэтому перед тем как что-либо выводить, Мы проверяем класс полученных данных. Если получен список, то проходимся по нему, последовательно извлекая данные.
Вот, в общем-то, и всё, что можно сказать о CGI-скриптах. Класс FieldStorage() прост в обращении, но при этом достаточно мощен, чтобы быть использованным в серьёзных серверных приложениях.
COOKIE.
Теперь поговорим о куках. Куки - это небольшие фрагменты данных, которые содержат в себе информацию, чаще всего связанную с личностью клиента или его активностью. Простой пример - автоматическая авторизация на сайте. Достаточно Вам один раз ввести свои данные, и в следующий раз, когда Вы зайдёте на сайт, куки самостоятельно передадут серверу информацию о Вас, позволяя войти под своей учётной записью автоматически.
Принцип работы:
Cookie генерируются сервером, обычно с помощью CGI-сценариев. Затем они отправляются клиенту и сохраняются на его компьютере. Когда, в очередной раз, клиент подключается к серверу, браузер отправляет ему(серверу) куки. Обрабатывая их, сервер "узнаёт" лицо клиента. Сложность, которая хоть и редко, но всё же возникает, связана с антивирусами - некоторые из них могут распознать куки, как нежелательные или вредоносные файлы. Команда на создание/приём сервером Cookie подаётся в виде HTTP-запроса. К счастью, модуль http включает в себя класс SimpleCookie(), который упрощает все эти процедуры. Сперва напишем такой CGI-скрипт:
| Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| import http.cookies,os
cookies=os.environ.get('HTTP_COOKIE')
cookies=http.cookies.SimpleCookie(cookies)
usercookies=cookies.get('user')
if usercookies==None:
message="""<p>Enter your name:</p>
<form method=POST action="cookcreate.py">
<input type=text name=login>
<input type=submit value=send>
</form>"""
else:
message='<p>Welcome back, %s</p>' % usercookies.value
print('Content-type: text/html\n')
print(message) |
|
Разберём поподробнее:
С помощью переменной окружения(os.environ.get('HTTP_COOKIE')), сервер определяет, доступны ли куки подключившегося клиента. Если нет, CGI-скрипт выведет форму для ввода, предлагая пользователю назвать своё имя, которое будет обработано уже другой программой(адрес, которой указан в прошлом скрипте, в параметре action):
| Python | 1
2
3
4
5
6
7
8
9
| import cgi
import http.cookies
form=cgi.FieldStorage()
cookies=http.cookies.SimpleCookie()
cookies['user']=form['login'].value
cookies['user']['expires']='expires=Monday, 4-March-2013 12:00:00 GMT'
print(cookies) |
|
Этот скрипт извлекает строку, введённую клиентом, и заносит её в куки. Обратите также внимание на то, что Мы включаем в объект ещё один атрибут - expires, в котором указано время уничтожения этого Cookie(ведь это временные файлы). Кроме всего прочего, в куки можно передать ещё один аргумент:
| Python | 1
| cookies['user']['domain']='www.xxxxx.com' |
|
, указывающий имя сервера, для которого они предназначены.
Теперь пришло время посмотреть, что получилось:
Если сервер не запущен, запускаем. Открываем браузер и в адресной строке вводим имя 1-го CGI-файла. У меня, например, оно выглядит так:
localhost/cgi-bin/cook2.py
, где localhost - указывает на то, что сервер расположен на этом же компьютере(папка cgi-bin, напоминаю, находится в том же каталоге, что и сервер).
В ответ Вы должны получить приглашение ко вводу и форму. Введите свой логин и нажмите кнопку "send". Второй CGI-скрипт ничего не выводит, только создаёт Cookie, поэтому Вы увидите пустую страницу. Теперь закройте браузер - сеанс окончен. По-хорошему, данные пользователя не сохраняются даже при переходе с одной страницы на другую. Однако, благодаря кукам, Вы можете смело открыть браузер(начать новый сеанс) и снова вписать адрес 1-го скрипта в адресную строку. В ответ Вы должны получить приветствие с обращением по имени, введённом Вами в прошлый раз.
На всякий случай повторю, из-за чего могут возникнуть ошибки в работе сервера/CGI/Cookie:- Не запущен скрипт-сервер.
- В HTML-документе неправильно указан адрес CGI-скрипта(параметр action, о method=POST тоже забывать не следует).
- Одинаковые имена форм в HTML-разметке там, где нужны разные и наоборот.
- Обращение к FieldStorage['key'], как к списку, когда он содержит один объект и наоборот.
- Неправильный заголовок expires или domain в куках. Не забывайте, что время в скрипте я поставил то, которое мне было удобно в момент написания статьи. У Вас оно должно быть другим(чтобы куки не уничтожились ещё до своего появления).
Если Вы ещё не заметили, в консоли, открытой сервером, выводятся ошибки, возникающие при его работе, так что всегда можно посмотреть, что пошло не так, как надо.
И напоследок, если Вы вносите в скрипты изменения, связанные с генерацией куков, следите за тем, чтобы они не перекрывались полями с уже созданными Cookies.
|