【问题标题】:Python BaseHTTPRequestHandler: Respond with JSONPython BaseHTTPRequestHandler:使用 JSON 响应
【发布时间】:2017-01-02 15:09:18
【问题描述】:

我有一个继承 BaseHTTPRequestHandler 并实现方法 do_POST 的 Python 类。

我目前只成功响应整数状态,例如200,在方法结束时使用如下命令:

self.send_response(200)

我也在尝试发送一些字符串作为响应的一部分。我该怎么做?

【问题讨论】:

    标签: python basehttpserver basehttprequesthandler


    【解决方案1】:

    至少在我的环境中(Python 3.7)我必须使用

    self.send_response(200)
    self.send_header('Content-Type', 'application/json')
    self.end_headers()
    self.wfile.write(json_str.encode(encoding='utf_8'))
    

    否则会抛出这个错误: TypeError:需要一个类似字节的对象,而不是'str'

    【讨论】:

    • 或者你可以像这样使用bytesself.wfile.write(bytes(json.dumps(object, ensure_ascii=False), 'utf-8'))
    【解决方案2】:

    其实很简单,虽然例子不多。

    只需使用:

    self.wfile.write(YOUR_STRING_HERE)
    

    专门针对json的情况:

    import json
    json_string = json.dumps(YOUR_DATA_STRUCTURE_TO_CONVERT_TO_JSON)
    self.wfile.write(json_string)
    

    【讨论】:

    • 这不起作用,write 需要一个二进制字符串,而 json.dumps 输出一个正常的字符串。您需要将其包装在 bytes(json.dumps(ASDASDF), 'utf-8')
    • 可能是Python2/3兼容性问题
    • @BjornW 使用 self.wfile.write(json_string.encode(encoding='utf_8')
    【解决方案3】:

    这是一个老问题。不过,如果其他人也有同样的疑问,这是我的 2 美分。

    如果你正在做任何有用的事情,除了玩 Python,你应该开始寻找标准的 Python 框架来处理 HTTP 服务器操作,比如 Django 或 Flask。

    话虽如此,我使用一个小存根作为我的传出请求的测试服务器,它应该可以回答您的问题。您可以通过修改设置任何状态码、标头或响应正文:

    #!/usr/bin/env python
    # Reflects the requests with dummy responses from HTTP methods GET, POST, PUT, and DELETE
    # Written by Tushar Dwivedi (2017)
    
    import json
    from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
    from optparse import OptionParser
    
    class RequestHandler(BaseHTTPRequestHandler):
    
        def do_GET(self):
            request_path = self.path
    
            print("\n----- Request Start ----->\n")
            print("request_path :", request_path)
            print("self.headers :", self.headers)
            print("<----- Request End -----\n")
    
            self.send_response(200)
            self.send_header("Set-Cookie", "foo=bar")
            self.end_headers()
            self.wfile.write(json.dumps({'hello': 'world', 'received': 'ok'}))
    
        def do_POST(self):
            request_path = self.path
    
            # print("\n----- Request Start ----->\n")
            print("request_path : %s", request_path)
    
            request_headers = self.headers
            content_length = request_headers.getheaders('content-length')
            length = int(content_length[0]) if content_length else 0
    
            # print("length :", length)
    
            print("request_headers : %s" % request_headers)
            print("content : %s" % self.rfile.read(length))
            # print("<----- Request End -----\n")
    
            self.send_response(200)
            self.send_header("Set-Cookie", "foo=bar")
            self.end_headers()
            self.wfile.write(json.dumps({'hello': 'world', 'received': 'ok'}))
    
        do_PUT = do_POST
        do_DELETE = do_GET
    
    
    def main():
        port = 8082
        print('Listening on localhost:%s' % port)
        server = HTTPServer(('', port), RequestHandler)
        server.serve_forever()
    
    
    if __name__ == "__main__":
        parser = OptionParser()
        parser.usage = ("Creates an http-server that will echo out any GET or POST parameters, and respond with dummy data\n"
                        "Run:\n\n")
        (options, args) = parser.parse_args()
    
        main()
    

    再一次,即使你只是在学习,甚至需要在上面加上5-6个if elses来做你正在做的事情,最好从头做起,避免很多未来的返工。使用能够为您处理样板文件的框架。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-15
      • 2013-12-20
      • 1970-01-01
      • 2011-01-26
      • 2012-05-19
      相关资源
      最近更新 更多