【问题标题】:Accessing Form Data Values in Python http.server Using CGI Module使用 CGI 模块在 Python http.server 中访问表单数据值
【发布时间】:2019-10-16 09:25:58
【问题描述】:

我正在尝试创建一个 Python Web 服务器,它接受用户输入并向第三方 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 文件并在浏览器中访问 http://localhost:8080/ 网址。但是,当我提交表单时,浏览器中出现错误。终端输出显示一个错误,提示“无法将“str”与“nonetype”连接起来。基于此错误,表单值未传递到此页面。无论是那个还是 HTTP 服务器都将它们作为查询参数传递。无论如何,我是否可以在我的 HTTP 服务器中使用 cgi.FieldStorage 类来访问表单字段值?

【问题讨论】:

    标签: python html cgi


    【解决方案1】:

    FieldStorage 类在this page 上定义了一个构造函数。重要的参数是fpheadersenviron。 OP 是正确的,因为 cgi.FieldStorage() 通常在 CGI 脚本中调用时不带参数,在这种情况下,参数会为您填写。但是,我们可以使用CGIHTTPRequestHandler 为我们提供的变量创建一个 FieldStorage 对象:

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

    【讨论】:

      【解决方案2】:

      在寻找解决方案大约一周后,我发现 http.server Python 模块与 cgi 模块并不真正兼容。 cgi 模块用于 Python 脚本内部,这些脚本从 Web 服务器上的某个 HTML 文档传递表单值(即 Web 服务器的 index.html 页面上的表单,其中“action”属性设置为相关 Python 脚本) .但是,为了让 cgi 模块能够访问传递给该脚本的表单值(通过 cgi.FieldStorage() 调用),该脚本必须在 Web 服务器内运行。我上面的代码示例的问题是我创建的 server.py 脚本本身就是一个 Web 服务器。具体来说,它使用我创建的自定义请求处理程序类 (TestServerHandler) 创建 HTTPServer 的实例。我的自定义类继承了 http.server 模块中包含的 CGIHTTPRequestHandler 类。此类包含 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 解析器从表单中访问您需要的值。

      【讨论】:

        猜你喜欢
        • 2020-11-19
        • 1970-01-01
        • 2013-06-10
        • 2019-06-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-01
        • 1970-01-01
        相关资源
        最近更新 更多