Python - Программирование CGI
Общий интерфейс шлюза или CGI - это набор стандартов, которые определяют, как происходит обмен информацией между веб-сервером и настраиваемым сценарием. Спецификации CGI в настоящее время поддерживаются NCSA.
Что такое CGI?
Общий интерфейс шлюза, или CGI, является стандартом для программ внешнего шлюза для взаимодействия с информационными серверами, такими как серверы HTTP.
Текущая версия - CGI / 1.1, а CGI / 1.2 находится в стадии разработки.
Просмотр веб-страниц
Чтобы понять концепцию CGI, давайте посмотрим, что происходит, когда мы щелкаем гиперссылку для просмотра определенной веб-страницы или URL-адреса.
Ваш браузер связывается с веб-сервером HTTP и запрашивает URL-адрес, то есть имя файла.
Веб-сервер анализирует URL-адрес и ищет имя файла. Если он находит этот файл, он отправляет его обратно в браузер, в противном случае отправляет сообщение об ошибке, указывающее, что вы запросили не тот файл.
Веб-браузер принимает ответ от веб-сервера и отображает полученный файл или сообщение об ошибке.
Однако можно настроить HTTP-сервер так, чтобы всякий раз, когда запрашивается файл в определенном каталоге, этот файл не отправлялся обратно; вместо этого он выполняется как программа, и все, что выводит эта программа, отправляется обратно в ваш браузер для отображения. Эта функция называется Common Gateway Interface или CGI, а программы называются сценариями CGI. Эти программы CGI могут быть скриптом Python, скриптом PERL, скриптом оболочки, программой C или C ++ и т. Д.
Схема архитектуры CGI
Поддержка и настройка веб-сервера
Прежде чем приступить к программированию CGI, убедитесь, что ваш веб-сервер поддерживает CGI и настроен для обработки программ CGI. Все программы CGI, выполняемые HTTP-сервером, хранятся в предварительно настроенном каталоге. Этот каталог называется CGI Directory и по соглашению называется / var / www / cgi-bin. По соглашению файлы CGI имеют расширение.cgi, но вы можете хранить свои файлы с расширением python .py также.
По умолчанию сервер Linux настроен на запуск только сценариев в каталоге cgi-bin в / var / www. Если вы хотите указать любой другой каталог для запуска ваших сценариев CGI, прокомментируйте следующие строки в файле httpd.conf -
<Directory "/var/www/cgi-bin">
AllowOverride None
Options ExecCGI
Order allow,deny
Allow from all
</Directory>
<Directory "/var/www/cgi-bin">
Options All
</Directory>
Здесь мы предполагаем, что у вас есть запущенный и успешно работающий веб-сервер, и вы можете запускать любую другую программу CGI, такую как Perl или Shell и т. Д.
Первая программа CGI
Вот простая ссылка, которая связана со сценарием CGI с именем hello.py . Этот файл хранится в каталоге / var / www / cgi-bin и имеет следующее содержимое. Перед запуском вашей программы CGI убедитесь, что у вас есть режим изменения файла, используяchmod 755 hello.py Команда UNIX для создания исполняемого файла.
#!/usr/bin/python
print "Content-type:text/html\r\n\r\n"
print '<html>'
print '<head>'
print '<title>Hello World - First CGI Program</title>'
print '</head>'
print '<body>'
print '<h2>Hello World! This is my first CGI program</h2>'
print '</body>'
print '</html>'
Если вы нажмете hello.py, это даст следующий результат:
Привет, мир! Это моя первая программа CGI |
Этот сценарий hello.py представляет собой простой сценарий Python, который записывает свой вывод в файл STDOUT, то есть на экран. Доступна одна важная и дополнительная функция - первая строка для печати.Content-type:text/html\r\n\r\n. Эта строка отправляется обратно в браузер, и в ней указывается тип содержимого, отображаемого на экране браузера.
К настоящему времени вы, должно быть, поняли базовую концепцию CGI и можете писать много сложных программ CGI, используя Python. Этот сценарий может взаимодействовать с любой другой внешней системой, а также для обмена информацией, такой как СУБД.
Заголовок HTTP
Линия Content-type:text/html\r\n\r\nявляется частью HTTP-заголовка, который отправляется браузеру для понимания содержимого. Весь HTTP-заголовок будет в следующей форме -
HTTP Field Name: Field Content
For Example
Content-type: text/html\r\n\r\n
Есть несколько других важных заголовков HTTP, которые вы часто будете использовать в программировании CGI.
Sr.No. | Заголовок и описание |
---|---|
1 | Content-type: Строка MIME, определяющая формат возвращаемого файла. Пример: Content-type: text / html |
2 | Expires: Date Дата, когда информация становится недействительной. Он используется браузером, чтобы решить, когда необходимо обновить страницу. Допустимая строка даты имеет формат 01 января 1998 12:00:00 GMT. |
3 | Location: URL URL-адрес, который возвращается вместо запрашиваемого URL-адреса. Вы можете использовать это поле для перенаправления запроса в любой файл. |
4 | Last-modified: Date Дата последней модификации ресурса. |
5 | Content-length: N Длина возвращаемых данных в байтах. Браузер использует это значение, чтобы сообщить приблизительное время загрузки файла. |
6 | Set-Cookie: String Установите cookie, передаваемый через строку |
Переменные среды CGI
Все программы CGI имеют доступ к следующим переменным среды. Эти переменные играют важную роль при написании любой программы CGI.
Sr.No. | Имя и описание переменной |
---|---|
1 | CONTENT_TYPE Тип данных содержимого. Используется, когда клиент отправляет прикрепленный контент на сервер. Например, загрузка файла. |
2 | CONTENT_LENGTH Длина информации запроса. Доступно только для запросов POST. |
3 | HTTP_COOKIE Возвращает установленные файлы cookie в виде пары ключ и значение. |
4 | HTTP_USER_AGENT Поле заголовка запроса User-Agent содержит информацию о пользовательском агенте, создавшем запрос. Это имя веб-браузера. |
5 | PATH_INFO Путь к сценарию CGI. |
6 | QUERY_STRING Информация в кодировке URL, отправляемая с запросом метода GET. |
7 | REMOTE_ADDR IP-адрес удаленного хоста, отправляющего запрос. Это полезно для ведения журнала или для аутентификации. |
8 | REMOTE_HOST Полное имя хоста, выполняющего запрос. Если эта информация недоступна, то для получения IR-адреса можно использовать REMOTE_ADDR. |
9 | REQUEST_METHOD Метод, использованный для отправки запроса. Наиболее распространены методы GET и POST. |
10 | SCRIPT_FILENAME Полный путь к сценарию CGI. |
11 | SCRIPT_NAME Имя сценария CGI. |
12 | SERVER_NAME Имя хоста или IP-адрес сервера |
13 | SERVER_SOFTWARE Название и версия программного обеспечения, на котором работает сервер. |
Вот небольшая программа CGI для вывода всех переменных CGI. Щелкните эту ссылку, чтобы увидеть результат Получить среду
#!/usr/bin/python
import os
print "Content-type: text/html\r\n\r\n";
print "<font size=+1>Environment</font><\br>";
for param in os.environ.keys():
print "<b>%20s</b>: %s<\br>" % (param, os.environ[param])
Методы GET и POST
Вы, должно быть, сталкивались со многими ситуациями, когда вам нужно было передать некоторую информацию из вашего браузера на веб-сервер и, в конечном итоге, в вашу программу CGI. Чаще всего браузер использует два метода, два из которых передают эту информацию веб-серверу. Это методы GET и POST.
Передача информации с использованием метода GET
Метод GET отправляет закодированную информацию о пользователе, добавленную к запросу страницы. Страница и закодированная информация разделяются знаком? характер следующим образом -
http://www.test.com/cgi-bin/hello.py?key1=value1&key2=value2
Метод GET - это метод по умолчанию для передачи информации из браузера на веб-сервер, и он создает длинную строку, которая появляется в поле Location: вашего браузера. Никогда не используйте метод GET, если у вас есть пароль или другая конфиденциальная информация для передачи на сервер. Метод GET имеет ограничение по размеру: в строке запроса можно отправить только 1024 символа. Метод GET отправляет информацию с помощью заголовка QUERY_STRING и будет доступен в вашей программе CGI через переменную среды QUERY_STRING.
Вы можете передать информацию, просто объединив пары ключ и значение вместе с любым URL-адресом, или вы можете использовать теги HTML <FORM> для передачи информации с помощью метода GET.
Пример простого URL: метод получения
Вот простой URL-адрес, который передает два значения программе hello_get.py с помощью метода GET.
/cgi-bin/hello_get.py?first_name=ZARA&last_name=ALIНиже hello_get.pyсценарий для обработки ввода данных веб-браузером. Мы собираемся использоватьcgi модуль, который позволяет очень легко получить доступ к переданной информации -
#!/usr/bin/python
# Import modules for CGI handling
import cgi, cgitb
# Create instance of FieldStorage
form = cgi.FieldStorage()
# Get data from fields
first_name = form.getvalue('first_name')
last_name = form.getvalue('last_name')
print "Content-type:text/html\r\n\r\n"
print "<html>"
print "<head>"
print "<title>Hello - Second CGI Program</title>"
print "</head>"
print "<body>"
print "<h2>Hello %s %s</h2>" % (first_name, last_name)
print "</body>"
print "</html>"
Это даст следующий результат -
Привет, ЗАРА Али |
Простой пример FORM: метод GET
В этом примере передаются два значения с использованием HTML FORM и кнопки отправки. Мы используем тот же CGI-скрипт hello_get.py для обработки этого ввода.
<form action = "/cgi-bin/hello_get.py" method = "get">
First Name: <input type = "text" name = "first_name"> <br />
Last Name: <input type = "text" name = "last_name" />
<input type = "submit" value = "Submit" />
</form>
Вот фактический результат вышеприведенной формы, вы вводите имя и фамилию, а затем нажимаете кнопку отправки, чтобы увидеть результат.
Передача информации с использованием метода POST
Обычно более надежным методом передачи информации программе CGI является метод POST. Это упаковывает информацию точно так же, как методы GET, но вместо того, чтобы отправлять ее в виде текстовой строки после символа? в URL-адресе он отправляет его как отдельное сообщение. Это сообщение поступает в сценарий CGI в виде стандартного ввода.
Ниже приведен тот же скрипт hello_get.py, который обрабатывает GET, а также метод POST.
#!/usr/bin/python
# Import modules for CGI handling
import cgi, cgitb
# Create instance of FieldStorage
form = cgi.FieldStorage()
# Get data from fields
first_name = form.getvalue('first_name')
last_name = form.getvalue('last_name')
print "Content-type:text/html\r\n\r\n"
print "<html>"
print "<head>"
print "<title>Hello - Second CGI Program</title>"
print "</head>"
print "<body>"
print "<h2>Hello %s %s</h2>" % (first_name, last_name)
print "</body>"
print "</html>"
Давайте снова возьмем тот же пример, что и выше, который передает два значения с помощью HTML FORM и кнопки отправки. Мы используем тот же CGI-скрипт hello_get.py для обработки этого ввода.
<form action = "/cgi-bin/hello_get.py" method = "post">
First Name: <input type = "text" name = "first_name"><br />
Last Name: <input type = "text" name = "last_name" />
<input type = "submit" value = "Submit" />
</form>
Вот фактический результат вышеуказанной формы. Вы вводите имя и фамилию, а затем нажимаете кнопку отправки, чтобы увидеть результат.
Передача данных флажка в программу CGI
Флажки используются, когда требуется выбрать более одного параметра.
Вот пример HTML-кода для формы с двумя флажками -
<form action = "/cgi-bin/checkbox.cgi" method = "POST" target = "_blank">
<input type = "checkbox" name = "maths" value = "on" /> Maths
<input type = "checkbox" name = "physics" value = "on" /> Physics
<input type = "submit" value = "Select Subject" />
</form>
Результатом этого кода является следующая форма -
Ниже приведен сценарий checkbox.cgi для обработки ввода, предоставленного веб-браузером для кнопки флажка.
#!/usr/bin/python
# Import modules for CGI handling
import cgi, cgitb
# Create instance of FieldStorage
form = cgi.FieldStorage()
# Get data from fields
if form.getvalue('maths'):
math_flag = "ON"
else:
math_flag = "OFF"
if form.getvalue('physics'):
physics_flag = "ON"
else:
physics_flag = "OFF"
print "Content-type:text/html\r\n\r\n"
print "<html>"
print "<head>"
print "<title>Checkbox - Third CGI Program</title>"
print "</head>"
print "<body>"
print "<h2> CheckBox Maths is : %s</h2>" % math_flag
print "<h2> CheckBox Physics is : %s</h2>" % physics_flag
print "</body>"
print "</html>"
Передача данных радиокнопки в программу CGI
Радиокнопки используются, когда требуется выбрать только один вариант.
Вот пример HTML-кода для формы с двумя переключателями -
<form action = "/cgi-bin/radiobutton.py" method = "post" target = "_blank">
<input type = "radio" name = "subject" value = "maths" /> Maths
<input type = "radio" name = "subject" value = "physics" /> Physics
<input type = "submit" value = "Select Subject" />
</form>
Результатом этого кода является следующая форма -
Ниже приведен скрипт radiobutton.py для обработки ввода, предоставленного веб-браузером для переключателя -
#!/usr/bin/python
# Import modules for CGI handling
import cgi, cgitb
# Create instance of FieldStorage
form = cgi.FieldStorage()
# Get data from fields
if form.getvalue('subject'):
subject = form.getvalue('subject')
else:
subject = "Not set"
print "Content-type:text/html\r\n\r\n"
print "<html>"
print "<head>"
print "<title>Radio - Fourth CGI Program</title>"
print "</head>"
print "<body>"
print "<h2> Selected Subject is %s</h2>" % subject
print "</body>"
print "</html>"
Передача данных текстовой области в программу CGI
Элемент TEXTAREA используется, когда многострочный текст должен быть передан программе CGI.
Вот пример HTML-кода для формы с полем TEXTAREA -
<form action = "/cgi-bin/textarea.py" method = "post" target = "_blank">
<textarea name = "textcontent" cols = "40" rows = "4">
Type your text here...
</textarea>
<input type = "submit" value = "Submit" />
</form>
Результатом этого кода является следующая форма -
Ниже приведен сценарий textarea.cgi для обработки ввода, предоставленного веб-браузером -
#!/usr/bin/python
# Import modules for CGI handling
import cgi, cgitb
# Create instance of FieldStorage
form = cgi.FieldStorage()
# Get data from fields
if form.getvalue('textcontent'):
text_content = form.getvalue('textcontent')
else:
text_content = "Not entered"
print "Content-type:text/html\r\n\r\n"
print "<html>"
print "<head>";
print "<title>Text Area - Fifth CGI Program</title>"
print "</head>"
print "<body>"
print "<h2> Entered Text Content is %s</h2>" % text_content
print "</body>"
Передача данных раскрывающегося списка в программу CGI
Выпадающий список используется, когда у нас много доступных вариантов, но будут выбраны только один или два.
Вот пример HTML-кода для формы с одним раскрывающимся списком -
<form action = "/cgi-bin/dropdown.py" method = "post" target = "_blank">
<select name = "dropdown">
<option value = "Maths" selected>Maths</option>
<option value = "Physics">Physics</option>
</select>
<input type = "submit" value = "Submit"/>
</form>
Результатом этого кода является следующая форма -
Ниже приведен сценарий dropdown.py для обработки ввода данных веб-браузером.
#!/usr/bin/python
# Import modules for CGI handling
import cgi, cgitb
# Create instance of FieldStorage
form = cgi.FieldStorage()
# Get data from fields
if form.getvalue('dropdown'):
subject = form.getvalue('dropdown')
else:
subject = "Not entered"
print "Content-type:text/html\r\n\r\n"
print "<html>"
print "<head>"
print "<title>Dropdown Box - Sixth CGI Program</title>"
print "</head>"
print "<body>"
print "<h2> Selected Subject is %s</h2>" % subject
print "</body>"
print "</html>"
Использование файлов cookie в CGI
Протокол HTTP - это протокол без сохранения состояния. Для коммерческого веб-сайта требуется поддерживать информацию о сеансе между разными страницами. Например, регистрация одного пользователя заканчивается после заполнения множества страниц. Как сохранить информацию о сеансе пользователя на всех веб-страницах?
Во многих ситуациях использование файлов cookie является наиболее эффективным методом запоминания и отслеживания предпочтений, покупок, комиссионных и другой информации, необходимой для лучшего взаимодействия с посетителями или статистики сайта.
Как это устроено?
Ваш сервер отправляет некоторые данные в браузер посетителя в виде файла cookie. Браузер может принять файл cookie. Если это так, он сохраняется в виде простой текстовой записи на жестком диске посетителя. Теперь, когда посетитель переходит на другую страницу вашего сайта, cookie доступен для поиска. После получения ваш сервер знает / запоминает, что было сохранено.
Файлы cookie представляют собой запись данных в виде простого текста из 5 полей переменной длины:
Expires- Дата истечения срока действия cookie. Если это поле пусто, срок действия cookie истечет, когда посетитель закроет браузер.
Domain - Доменное имя вашего сайта.
Path- Путь к каталогу или веб-странице, которая устанавливает cookie. Это может быть пустое поле, если вы хотите получить cookie из любого каталога или страницы.
Secure- Если это поле содержит слово «безопасный», то файл cookie может быть получен только с помощью безопасного сервера. Если это поле пустое, такое ограничение отсутствует.
Name=Value - Файлы cookie устанавливаются и извлекаются в виде пар ключ-значение.
Настройка файлов cookie
Отправить файлы cookie в браузер очень просто. Эти файлы cookie отправляются вместе с заголовком HTTP до поля Content-type. Предполагая, что вы хотите установить UserID и Password как файлы cookie. Настройка файлов cookie выполняется следующим образом -
#!/usr/bin/python
print "Set-Cookie:UserID = XYZ;\r\n"
print "Set-Cookie:Password = XYZ123;\r\n"
print "Set-Cookie:Expires = Tuesday, 31-Dec-2007 23:12:40 GMT";\r\n"
print "Set-Cookie:Domain = www.tutorialspoint.com;\r\n"
print "Set-Cookie:Path = /perl;\n"
print "Content-type:text/html\r\n\r\n"
...........Rest of the HTML Content....
Из этого примера вы, должно быть, поняли, как устанавливать файлы cookie. Мы используемSet-Cookie Заголовок HTTP для установки файлов cookie.
Необязательно устанавливать такие атрибуты файлов cookie, как Expires, Domain и Path. Примечательно, что файлы cookie устанавливаются перед отправкой волшебной строки"Content-type:text/html\r\n\r\n.
Получение файлов cookie
Получить все установленные файлы cookie очень просто. Файлы cookie хранятся в переменной среды CGI HTTP_COOKIE, и они будут иметь следующую форму:
key1 = value1;key2 = value2;key3 = value3....
Вот пример того, как получить файлы cookie.
#!/usr/bin/python
# Import modules for CGI handling
from os import environ
import cgi, cgitb
if environ.has_key('HTTP_COOKIE'):
for cookie in map(strip, split(environ['HTTP_COOKIE'], ';')):
(key, value ) = split(cookie, '=');
if key == "UserID":
user_id = value
if key == "Password":
password = value
print "User ID = %s" % user_id
print "Password = %s" % password
Это дает следующий результат для файлов cookie, установленных указанным выше сценарием:
User ID = XYZ
Password = XYZ123
Пример загрузки файла
Чтобы загрузить файл, HTML-форма должна иметь атрибут enctype, установленный на multipart/form-data. Тег ввода с типом файла создает кнопку «Обзор».
<html>
<body>
<form enctype = "multipart/form-data"
action = "save_file.py" method = "post">
<p>File: <input type = "file" name = "filename" /></p>
<p><input type = "submit" value = "Upload" /></p>
</form>
</body>
</html>
Результатом этого кода является следующая форма -
Приведенный выше пример был намеренно отключен, чтобы сохранить людей, загружающих файл на наш сервер, но вы можете попробовать приведенный выше код со своим сервером.
Вот сценарий save_file.py для обработки загрузки файла -
#!/usr/bin/python
import cgi, os
import cgitb; cgitb.enable()
form = cgi.FieldStorage()
# Get filename here.
fileitem = form['filename']
# Test if the file was uploaded
if fileitem.filename:
# strip leading path from file name to avoid
# directory traversal attacks
fn = os.path.basename(fileitem.filename)
open('/tmp/' + fn, 'wb').write(fileitem.file.read())
message = 'The file "' + fn + '" was uploaded successfully'
else:
message = 'No file was uploaded'
print """\
Content-Type: text/html\n
<html>
<body>
<p>%s</p>
</body>
</html>
""" % (message,)
Если вы запустите приведенный выше сценарий в Unix / Linux, вам необходимо позаботиться о замене разделителя файлов следующим образом, в противном случае на вашем компьютере с Windows вышеупомянутый оператор open () должен работать нормально.
fn = os.path.basename(fileitem.filename.replace("\\", "/" ))
Как открыть диалоговое окно "Загрузка файла"?
Иногда желательно предоставить вариант, при котором пользователь может щелкнуть ссылку, и пользователю будет выведено диалоговое окно «Загрузка файла» вместо отображения фактического содержимого. Это очень просто и может быть достигнуто через HTTP-заголовок. Этот заголовок HTTP отличается от заголовка, упомянутого в предыдущем разделе.
Например, если вы хотите сделать FileName файл, загружаемый по заданной ссылке, то его синтаксис следующий:
#!/usr/bin/python
# HTTP Header
print "Content-Type:application/octet-stream; name = \"FileName\"\r\n";
print "Content-Disposition: attachment; filename = \"FileName\"\r\n\n";
# Actual File Content will go here.
fo = open("foo.txt", "rb")
str = fo.read();
print str
# Close opend file
fo.close()
Надеюсь, вам понравился этот урок. Если да, отправьте мне свой отзыв по адресу: Свяжитесь с нами