do_POST过程中的KeyError,但密钥存在

时间:2017-07-27 04:31:31

标签: python http

这是我的网络服务器根据GET请求提供的表单(以及内存列表的内容)。我试图这样做,以便在提交消息时,它被附加到内存中。表格如下:

form = ''' <!DOCTYPE html><html><head><title>Server</title></head><body>
           <form action="/basic-server.py" method="post">
           <label>Message <input name="message" type="text" /></label>
           </form>
           </body></html> '''

memory = []

现在这里是我使用BasicHTTPRequestHandler的POST方法的内容:

def do_POST(self):

    length = int(self.headers.get('Content-Length'))
    postvars = parse.parse_qs(self.rfile.read(length))
    memory.append(postvars["message"])

    self.send_response(303)
    self.send_header('Location', '/')
    self.end_headers()

它会为&#39;消息&#39;抛出KeyError。令我困惑的是,如果我删除该行并打印出postvars,它看起来像一个带有&#34;消息的字典&#34;包含我在表单上输入的消息的密钥。

如果我使用memory.append(postvars)并输入&#39; test&#39;该应用程序工作并附加以下字典:{b'message': [b'test']}。什么&#39;&#39;&#39;字符?如果我使用[b'message']作为键,它可以工作,但会将[b'test']返回到内存而不是简单地测试。

1 个答案:

答案 0 :(得分:2)

修复

您需要解码通过帖子请求推送的信息。

之前

postvars = parse.parse_qs(self.rfile.read(length))

应该成为......

postvars = parse.parse_qs(self.rfile.read(length).decode())

解释

在原始代码中,postvars是字节文字而不是字符串文字的字典。 Here is a good explanation of this.

所以在之前postvars == [{b'message': [b'Post Message']}],意味着键和值都是字节文字。您不能将字符串['message']用作键,因为键是字节实例,而不是字符串实例。这里的关键是[b'message']

之后postvars变为[{'message': ['Test']}] - 键和值现在按预期解码为字符串实例。