简体   繁体   English

无法使用cgi.FieldStorage获取POST值

[英]Cannot get POST values with cgi.FieldStorage

I`m trying to send simple html page with form data to user with GET, and then receive variables from form with POST. 我试图通过GET向表单数据发送带有表单数据的简单html页面,然后通过POST从表单接收变量。 HTML file looks like: HTML文件看起来像:

<HTML>
<title> My Title</title>
<body>
<form  method="post" action="http.py">
<input name="Name" type="text"/>
<input name="Submit" type="submit" value="Submit" />
</form>
</body>
</HTML>

Here is python script: 这是python脚本:

import os
import cgi
import sys
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler



class customHTTPServer(BaseHTTPRequestHandler):
        def do_GET(self):
                self.send_response(200)
                self.send_header('Content-type', 'text/html')
                self.end_headers()
                fh=open('index.html','r')
                self.wfile.write(fh.read())
                return

        def do_POST(self):
            form = cgi.FieldStorage()
            self.send_response(200)
            self.end_headers()
            self.wfile.write(form['Name'].value)


def main():
       try:
            server = HTTPServer(('',9111),customHTTPServer)
            print 'server started at port 8080'
            server.serve_forever()
       except KeyboardInterrupt:
            server.socket.close()

if __name__=='__main__':
       sys.exit(main())

But FieldStorage remains empty all the time. 但FieldStorage一直都是空的。 I already tried to check what is in self.rfile, and found that if i try to do self.rfile.readlines() , browser stuck and looks like script is waiting for the end of data stream. 我已经尝试检查self.rfile中的内容,并发现如果我尝试执行self.rfile.readlines(),浏览器卡住并看起来像脚本正在等待数据流的结束。 From where i should take Name variable that i`m submitting with POST? 我应该从哪里采取我用POST提交的Name变量?

In the original code, I just changed the line 在原始代码中,我只是更改了行

form = cgi.FieldStorage()

to

form = cgi.FieldStorage(
    fp=self.rfile,
    headers=self.headers,
    environ={'REQUEST_METHOD':'POST'})

and it seems to work as you intended. 它似乎按你的意图工作。

Hat-tip to http://pymotw.com/2/BaseHTTPServer/ for the critical 'environ' setting. 对于关键的“环境”设置,请访问http://pymotw.com/2/BaseHTTPServer/ (By default, cgi.FieldStorage thinks it's dealing with a GET request.) (默认情况下,cgi.FieldStorage认为它正在处理GET请求。)

I think you might be mixing some concepts here. 我想你可能会在这里混合一些概念。 You have both the idea of a server and also a cgi script. 你既有服务器的想法,也有cgi脚本。 No matter what your POST action is (http.py or whatever), your server is just going to take in a request. 无论您的POST操作是什么(http.py或其他),您的服务器都将接收请求。 No CGI processing is actually happening. 实际上没有CGI处理。 So you can first adjust your html template to this for simplicity: 因此,为了简单起见,您可以先将html模板调整为此:

<form  method="post" action="">

Then, you should reference this other question about how to read from the request , as opposed to trying to use the cgi fieldstorage: 然后,您应该参考另一个关于如何从请求中读取的问题,而不是尝试使用cgi fieldstorage:

import urlparse

...

    def do_POST(self):
        length = int(self.headers.getheader('content-length'))
        postvars = urlparse.parse_qs(self.rfile.read(length), keep_blank_values=1)
        self.send_response(200)
        self.end_headers()
        self.wfile.write(postvars)

The issue you were having, and because this is a very low level way to create a web server app, if you read indefinitely from the input stream, it will keep going and block. 您遇到的问题,并且因为这是创建Web服务器应用程序的一种非常低级的方式,如果您无限期地从输入流中读取它,它将继续运行并阻止。 You check the header for the content length and only read that many bytes. 检查内容长度的标头,只读取那么多字节。 You don't have any need for the cgi module at all, because this is not a cgi script. 您根本不需要cgi模块,因为这不是cgi脚本。

A cgi script works by the server seeing the request is for a file of a matching type and location, and executing it in a subprocess like a normal program. cgi脚本由服务器工作,看到请求是针对匹配类型和位置的文件,并在子进程中执行它,就像普通程序一样。 It feeds the process the args and then gets back a response to ship back to the client. 它为args提供进程,然后返回响应以返回给客户端。 If this were a cgi script, the server would be in one module, running forever, and the cgi code would be in another with much simpler code to check the request. 如果这是一个cgi脚本,服务器将在一个模块中,永远运行,而cgi代码将在另一个模块中使用更简单的代码来检查请求。

以下是在我的案例中获取POST变量的方法的URL 这里详细说明由JDI提供。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM