首页 > 解决方案 > Python BaseHTTPRequestHandler 在除 utf-8 之外的任何内容上引发查找错误

问题描述

我需要在 Python 中编写一个服务器程序,为网页提供服务,并处理来自客户端的其他 GET 和 POST 请求。我是 Python 中服务器的新手,所以我查找了一些示例,过​​了一会儿,我运行了一个基本的 Requesthandler,并以一些路由到我的页面作为开始。路由在浏览器中工作,页面显示在那里,但我只有文本,没有样式,没有图片。然后我进一步观察并意识到我还需要处理这些 .css、.js、.jpg 文件的 GET 请求。所以我这样做了,结果是这样的:

class Serv(BaseHTTPRequestHandler):
    def do_GET(self):
        #route incoming path to correct page
        if self.path in("","/"):
            self.path = "/my_site/index.html"

        #TODO do same for every page in the site

        if self.path == "/foo":
            self.path = "/my_site/fooandstuff.html"

        if self.path == "/bar":
            self.path = "/my_site/subdir/barfly.html"


        try:
            sendReply = False
            if self.path.endswith(".html"):
                mimetype = "text/html"
                sendReply = True
            if self.path.endswith(".jpg"):
                mimetype = "image/jpg"
                sendReply = True
            if self.path.endswith(".js"):
                mimetype = "application/javascript"
                sendReply = True
            if self.path.endswith(".css"):
                mimetype = "text/css"
                sendReply = True

            if sendReply == True:
                f = open(self.path[1:]).read()
                self.send_response(200)
                self.send_header('Content-type',mimetype)
                self.end_headers()
                self.wfile.write(f.encode(mimetype))
            return
        except IOError:
            self.send_error(404, "File not found %s" % self.path)

当我运行它并请求一个页面时,我得到以下 LookupError:

  File "d:/somedir/myfile.py", line 47, in do_GET
    self.wfile.write(f.encode(mimetype))
LookupError: unknown encoding: text/html

如果我将 text/html 更改为 utf-8,这似乎“解决”了问题,但随后我遇到了相同的 Lookuperror,但这次是 image/jpg,等等。似乎 wfile.write 只接受 utf-8,但是,当我环顾四周时,我看到人们将 file.read() 传递给 wfile.write

wfile.write(file.read())

对他们来说,这似乎有效。然而,当我这样做时,我得到的是

File "C:\Users\myuser\AppData\Local\Programs\Python\Python37\lib\socketserver.py", line 799, in write
    self._sock.sendall(b)
TypeError: a bytes-like object is required, not 'str'

什么可能导致这种情况发生?

标签: pythonserverbasehttprequesthandler

解决方案


答案是打开一个图像文件,它需要一个额外的参数 "rb" ,如下所示:

        if mimetype != "image/jpg":
            f = open(self.path[1:])
        else:
            f = open(self.path[1:], "rb")

然后还有:

        if mimetype == "image/jpg": 
            self.wfile.write(f.read())
        else:
            self.wfile.write(f.read().encode("utf-8"))

推荐阅读