为什么在SimpleHttpServer捕获时从浏览器发送的表单与请求之间存在差异

时间:2017-04-04 13:27:34

标签: python http python-requests simplehttpserver

我有一个带有`do_POST'的SimleHttpServer功能

def do_POST(self):

    print self.path

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

现在问题是,如果我用浏览器发送请求(这样的HTML表单)

<form method="post" action="/">
  <input type="text" name="a" value="1"><br>
  <input type="submit" value="Send">
</form>

然后值是:

self.path = /
form.keys = [a]

如果我使用python请求发送相同的请求

parameters = {
    "a": 2,
}

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64)",
    "Content-Type": "application/x-www-form-urlencoded",
    "Referer": "http://127.0.0.1:8001/",
    "Host": "127.0.0.1:8001",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Encoding": "gzip, deflate",
    "Connection": "keep-alive",
    "Upgrade-Insecure-Requests": "1",
}

r = requests.post("http://127.0.0.1:8001", params=parameters, headers=headers)

服务器上的值是

self.path = /?a=2
form.keys = []

问题出在哪里?有什么不同吗?我从浏览器复制了标题,所以一切都应该是一样的。

提前感谢任何帮助或线索。

工作解决方法:

如果您遇到此问题,可以在do_POST中使用以下解决方法(您需要导入cgi,urlparse):

    if "?" in self.path:
        qs = self.path.split("?")[1]
        query_dict = dict(urlparse.parse_qsl(qs))
    else:       
        form = cgi.FieldStorage(
            fp=self.rfile, 
            headers=self.headers,
            environ={'REQUEST_METHOD':'POST',
                     'CONTENT_TYPE':self.headers['Content-Type'],
            })
        query_dict = {key: form.getvalue(key) for key in form.keys()}

但这不是问题的答案。

1 个答案:

答案 0 :(得分:1)

如果您想以POST格式发送数据(即不是GET查询字符串参数),则应将其作为data参数传递,而不是params

  

通常,您希望发送一些表单编码数据 - 非常类似于HTML   形成。为此,只需将字典传递给data参数即可。   您的数据字典将自动进行表单编码   请求

(资料来源:More complicated POST requests

  

params - (可选)要在查询中发送的字典或字节   请求的字符串

     

data - (可选)字典或列表   元组[(键,值)](将采用表单编码),字节或类文件   要在正文中发送的对象

(来源:Main Interface,强调我的)