我正在尝试创建一个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类访问表单字段值?
答案 0 :(得分:0)
在寻找解决方案大约一周后,我发现http.server Python模块与cgi模块并不真正兼容。 cgi模块在Python脚本内部使用,该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解析器从表单访问所需的值。
答案 1 :(得分:0)
FieldStorage类具有在this page上定义的构造函数。重要的参数是fp
,headers
和environ
。 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'],
}