Python - CGI Programming: Руководство для начинающих
Привет, будущие маги Python! Я рад быть вашим проводником в этом захватывающем путешествии по миру CGI-программирования на Python. Как человек, который многие годы преподает информатику, я могу вам сказать, что CGI - это как секретный соус, который делает ваши веб-приложения живыми. Так что принимайтеся за работу!
Что такое CGI?
CGI означает Common Gateway Interface. Это звучит сложно, но представьте, что это переводчик между вашим веб-сервером и скриптами на Python. Это как доброжелательный интерпретатор, который помогает вашему серверу и коду общаться без сбоев.
CGI позволяет нам создавать динамические веб-страницы, которые могут реагировать на ввод пользователя. Представьте себе веб-сайт, который приветствует вас по имени или показывает вам персонализированный контент - это и есть магия CGI!
Веб-браузинг
Прежде чем погружаться в детали CGI, давайте быстро рассмотрим, как работает веб-браузинг. Когда вы вводите URL в браузер, происходит следующее:
- Ваш браузер отправляет запрос на веб-сервер.
- Веб-сервер обрабатывает запрос.
- Сервер отправляет ответ, обычно в виде HTML-страницы.
- Ваш браузер отображает эту HTML, показывая веб-страницу, которую вы видите.
CGI вступает в игру, когда мы хотим генерировать динамический контент на шаге 3.
Диаграмма архитектуры CGI
Вот простая диаграмма для визуализации того, как CGI вписывается в веб-архитектуру:
+-------------+ HTTP Request +-------------+
| Браузер | -----------------> | Веб-сервер |
| | <----------------- | |
+-------------+ HTTP Response +-------------+
|
| CGI
v
+-------------+
| CGI Скрипт |
| (Python) |
+-------------+
Поддержка и конфигурация веб-сервера
Большинство веб-серверов поддерживают CGI, включая Apache и Nginx. Чтобы использовать CGI с Python, вам нужно настроить свой сервер, чтобы он выполнял Python-скрипты. Это обычно включает создание специального каталога для CGI-скриптов и указание серверу, что файлы в этом каталоге являются исполняемыми.
Например, в Apache вы можете добавить что-то вроде этого в вашу конфигурацию:
<Directory /var/www/cgi-bin>
Options ExecCGI
AddHandler cgi-script .py
</Directory>
Это указывает Apache выполнять .py файлы в каталоге /var/www/cgi-bin как CGI-скрипты.
Первый CGI-программ
Давайте напишем нашу первую CGI-программу! Начнем с классического примера "Hello, World!". Создайте файл с именем hello.py
в вашем каталоге CGI:
#!/usr/bin/env python3
print("Content-Type: text/html")
print()
print("<html>")
print("<head>")
print("<title>Hello World - Первая CGI программа</title>")
print("</head>")
print("<body>")
print("<h2>Hello World! Это моя первая CGI программа</h2>")
print("</body>")
print("</html>")
Разберем это:
- Первая строка указывает сервер использовать Python для выполнения этого скрипта.
-
Content-Type: text/html
- это HTTP-заголовок, который сообщает браузеру, что мы отправляем HTML. - Пустая
print()
отделяет заголовки от тела ответа. - Остальное просто HTML, который мы генерируем динамически.
Когда вы откроете этот скрипт через веб-браузер, вы увидите страницу с текстом "Hello World! Это моя первая CGI программа".
HTTP-заголовок
В программировании CGI важно отправлять правильные HTTP-заголовки перед вашим контентом. Самый распространенный заголовок - это Content-Type
, который сообщает браузеру, какой тип данных вы отправляете. Вот несколько примеров:
Тип контента | Описание |
---|---|
text/html | HTML-контент |
text/plain | Простой текст |
image/jpeg | JPEG-изображение |
application/json | JSON-данные |
Не забывайте всегда отправлять соответствующий Content-Type заголовок перед вашим контентом!
Переменные среды CGI
CGI-скрипты имеют доступ к различным переменным среды, которые предоставляют информацию о запросе. Вот скрипт, который отображает некоторые из этих переменных:
#!/usr/bin/env python3
import os
print("Content-Type: text/html")
print()
print("<html><body>")
print("<h2>Переменные среды:</h2>")
for param in os.environ.keys():
print(f"<b>{param:20}</b>: {os.environ[param]}<br>")
print("</body></html>")
Этот скрипт покажет вам все переменные среды, доступные вашему CGI-скрипту, включая такие как тип браузера пользователя, имя сервера и многое другое.
Методы GET и POST
Есть два основных метода для отправки данных в CGI-скрипт: GET и POST. Рассмотрим оба:
Метод GET
Метод GET отправляет данные как часть URL. Вот простой пример:
#!/usr/bin/env python3
import cgi
print("Content-Type: text/html")
print()
form = cgi.FieldStorage()
name = form.getvalue('name', 'Мир')
print("<html><body>")
print(f"<h2>Привет, {name}!</h2>")
print("</body></html>")
Вы можете получить доступ к этому скрипту с URL, таким как http://вашсервер.com/cgi-bin/hello.py?name=Алиса
, и он скажет "Привет, Алиса!".
Метод POST
Метод POST отправляет данные в теле HTTP-запроса. Обычно он используется для форм. Вот пример:
#!/usr/bin/env python3
import cgi
print("Content-Type: text/html")
print()
form = cgi.FieldStorage()
name = form.getvalue('name', 'Мир')
email = form.getvalue('email', 'Не указан')
print("<html><body>")
print(f"<h2>Привет, {name}!</h2>")
print(f"<p>Ваш email: {email}</p>")
print("</body></html>")
Этот скрипт можно использовать с HTML-формой, которая использует метод POST.
Обработка различных элементов формы
CGI может обрабатывать различные элементы формы. Рассмотрим несколько примеров:
Флажки (Checkbox)
#!/usr/bin/env python3
import cgi
print("Content-Type: text/html")
print()
form = cgi.FieldStorage()
hobbies = form.getlist('hobby')
print("<html><body>")
print("<h2>Ваши хобби:</h2>")
for hobby in hobbies:
print(f"<p>{hobby}</p>")
print("</body></html>")
Радио-кнопки (Radio Buttons)
#!/usr/bin/env python3
import cgi
print("Content-Type: text/html")
print()
form = cgi.FieldStorage()
gender = form.getvalue('gender', 'Не указан')
print("<html><body>")
print(f"<h2>Ваш пол: {gender}</h2>")
print("</body></html>")
Текстовая область (Text Area)
#!/usr/bin/env python3
import cgi
print("Content-Type: text/html")
print()
form = cgi.FieldStorage()
message = form.getvalue('message', 'Сообщение не указано')
print("<html><body>")
print("<h2>Ваше сообщение:</h2>")
print(f"<p>{message}</p>")
print("</body></html>")
Выпадающий список (Drop Down Box)
#!/usr/bin/env python3
import cgi
print("Content-Type: text/html")
print()
form = cgi.FieldStorage()
country = form.getvalue('country', 'Не выбрано')
print("<html><body>")
print(f"<h2>Ваша страна: {country}</h2>")
print("</body></html>")
Использование куки в CGI
Куки - это способ хранить небольшие фрагменты данных на стороне клиента. Они полезны для запоминания предпочтений пользователя или поддержания информации о сессии. Вот как можно работать с куки в CGI:
Установка кук
#!/usr/bin/env python3
import cgi
from http import cookies
import datetime
# Создаем куку
c = cookies.SimpleCookie()
c['lastvisit'] = str(datetime.datetime.now())
c['lastvisit']['expires'] = 365 * 24 * 60 * 60 # истекает через год
print(c) # Это выводит заголовок Set-Cookie
print("Content-Type: text/html")
print()
print("<html><body>")
print("<h2>Кука установлена!</h2>")
print("</body></html>")
Получение кук
#!/usr/bin/env python3
import os
from http import cookies
print("Content-Type: text/html")
print()
if 'HTTP_COOKIE' in os.environ:
cookie_string = os.environ.get('HTTP_COOKIE')
c = cookies.SimpleCookie()
c.load(cookie_string)
lastvisit = c.get('lastvisit')
if lastvisit:
print(f"<h2>Ваш последний визит был: {lastvisit.value}</h2>")
else:
print("<h2>Это ваш первый визит!</h2>")
else:
print("<h2>Это ваш первый визит!</h2>")
Пример загрузки файла
Обработка загрузки файлов немного сложнее, но вот простой пример:
#!/usr/bin/env python3
import cgi, os
import cgitb; cgitb.enable()
print("Content-Type: text/html")
print()
form = cgi.FieldStorage()
# Получаем имя файла здесь.
fileitem = form['filename']
# Проверяем, был ли файл загружен
if fileitem.filename:
# Обрезаем ведущий путь от имени файла, чтобы избежать
# атак по переходу каталогов
fn = os.path.basename(fileitem.filename)
open('/tmp/' + fn, 'wb').write(fileitem.file.read())
message = f'Файл "{fn}" был успешно загружен'
else:
message = 'Файл не был загружен'
print(f"""\
<html>
<body>
<p>{message}</p>
</body>
</html>
""")
Как вызвать диалоговое окно "Загрузка файла"?
Чтобы вызвать диалоговое окно загрузки файла, вам нужно установить соответствующие заголовки:
#!/usr/bin/env python3
import os
filename = "example.txt" # Это будет ваше имя файла
filepath = "/path/to/your/file" # Это будет путь к вашему файлу
print("Content-Type: application/octet-stream")
print(f"Content-Disposition: attachment; filename={filename}")
print() # Пустая строка, конец заголовков
# Теперь отправляем содержимое файла
with open(os.path.join(filepath, filename), 'rb') as f:
print(f.read())
Этот скрипт устанавливает Content-Type на application/octet-stream
, что указывает браузеру загружать файл, а не отображать его. Заголовок Content-Disposition предлагает имя файла для загрузки.
Итак, это базовые знания о CGI-программировании на Python. Помните, практика - это ключ к успеху, так что не стесняйтесь экспериментировать с этими примерами и создавать свои собственные. Счастливого кодинга, и愿 ваши CGI-скрипты всегда работали гладко!
Credits: Image by storyset