Доступ к значениям данных формы в Python http.server с использованием модуля CGI

Я пытаюсь создать веб-сервер Python, который принимает пользовательский ввод и отправляет запрос стороннему API. Пользовательский ввод осуществляется через простую форму, которую я создал.

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <meta name = "viewport" content = "width=device-width, initial-scale=1.0">
    <meta http-equiv = "X-UA-Compatible" content = "ie=edge">
    <title>Test Document</title>
</head>
<body>
    <form action = "server.py" method = "post">
        <label for = "firstname">First Name</label>
        <input type = "text" name = "firstname" id = "firstname"><br>
        <label for = "lastname">Last Name</label>
        <input type = "text" name = "lastname" id = "lastname"><br>
        <label for = "url">URL</label>
        <input type = "text" name = "url" id = "application-url"><br>
        <input type = "submit" value = "Submit">
    </form>
</body>
</html>

Я назвал этот файл index.html. Мой файл server.py выглядит так:

import cgi
from http.server import HTTPServer, CGIHTTPRequestHandler

class TestServerHandler(CGIHTTPRequestHandler):
    def do_POST(self):
        if self.path == '/':
            self.path = './index.html'

        try:
            form = cgi.FieldStorage()
            firstname = form.getvalue('firstname')
            lastname = form.getvalue('lastname')
            url = form.getvalue('url')
            print(firstname + ' ' + lastname + ' ' + url)
            output=firstname + lastname + url
        except: 
            self.send_error(404, 'Bad request submitted.')

        self.end_headers()
        self.wfile.write(bytes(output, 'utf-8'))


test_server = HTTPServer(('localhost', 8080), TestServerHandler)
test_server.serve_forever()

Затем я запускаю файл server.py на своем терминале и перехожу по URL-адресу http://локальный:8080/ в своем браузере. Однако, когда я отправляю форму, я получаю сообщение об ошибке в браузере. Вывод терминала показывает ошибку, в которой говорится, что «невозможно объединить «str» с «nonetype». Из-за этой ошибки значения формы не передаются на эту страницу. Либо так, либо HTTP-сервер передает их в качестве параметров запроса. В любом случае, смогу ли я использовать класс cgi.FieldStorage внутри моего HTTP-сервера для доступа к значениям полей формы?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
2 981
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Примерно через неделю поиска решения этой проблемы я обнаружил, что модуль http.server Python на самом деле несовместим с модулем cgi. Модуль cgi используется внутри сценариев Python, которым передаются значения формы из некоторого документа HTML на веб-сервере (например, форма на странице index.html веб-сервера с атрибутом «действие», установленным для рассматриваемого сценария Python) . Однако для того, чтобы модуль cgi имел доступ к значениям формы, переданным этому сценарию (через вызов cgi.FieldStorage()), сценарий должен выполняться внутри веб-сервера. Проблема с моим примером кода выше заключается в том, что сценарий server.py, который я создал, сам является веб-сервером. В частности, он создает экземпляр HTTPServer, используя собственный класс обработчика запросов, который я создаю (TestServerHandler). Мой пользовательский класс является подклассом класса CGIHTTPRequestHandler, содержащегося в модуле http.server. Этот класс содержит метод Do_POST. При реализации этого метода любые данные формы, передаваемые сценарию Python, содержатся внутри переменной экземпляра self.rfile. Чтобы получить доступ к этой переменной и получить данные формы, я написал код, подобный этому.

content_length = int(self.headers['Content-Length'])
data_input = bytes.decode(self.rfile.read(content_length))

После того, как вы сохранили form_data в переменной data_input, вы можете использовать анализатор URL для доступа к нужным вам значениям из формы.

Класс FieldStorage имеет конструктор, определенный для эта страница. Важными параметрами являются fp, headers и environ. OP прав в том, что cgi.FieldStorage() обычно вызывается без параметров в сценарии CGI, и в этом случае параметры заполняются за вас. Однако мы можем создать объект FieldStorage с переменными, которые нам предоставляет CGIHTTPRequestHandler:

form = cgi.FieldStorage(
        fp=self.rfile,
        headers=self.headers,
        environ = {
            'REQUEST_METHOD': 'POST',
            'CONTENT_TYPE': self.headers['Content-Type'],
        }

Другие вопросы по теме