0

在 python 3.8 上,我使用模块 http.server 中的 BaseHTTPRequestHandler 和 HTTPServer 为我的学生创建了一个简约的 python 服务器

当我转到服务器上的 url 时,我在浏览器调试工具中看到两个 http 请求:

  • 一个用于页面
  • 一个用于favicon(当前head html页面不包含favicon的链接标签,当前head为空)

在此处输入图像描述

我想阻止第二个请求(对于 favicon)。我的问题是:使用“BaseHTTPRequestHandler”和“HTTPServer”类是否可以自定义生成页面的标题?我正在寻找一种方法来添加这样的空图标<link rel="icon" href="data:;base64,=">:(https://stackoverflow.com/a/13416784/2137454

4

2 回答 2

0

这显然是可能的。毕竟,您可以完全控制服务器向客户端发送的内容。但是,我认为你不应该这样做。只需提供那个烦人的小文件 favicon.ico。这是最简单的方法:

import socketserver
from http.server import SimpleHTTPRequestHandler


class CustomHttpRequestHandler(SimpleHTTPRequestHandler):

    def do_GET(self):
        if self.path == '/':
            # here do whatever your custom server would normally do
            self.path = 'static/index.html'

        if self.path == '/favicon.ico':
            self.path = 'static/favicon.ico'

        return SimpleHTTPRequestHandler.do_GET(self)


if __name__ == '__main__':
    PORT = 8001
    my_server = socketserver.TCPServer(("", PORT), CustomHttpRequestHandler)
    my_server.serve_forever()

要完成这项工作,您需要做的就是将 png 文件放在文件夹中static并将其命名为favicon.ico.

当然,您也可以修改您发送的 html 内容。由于您的问题中没有代码,因此我一起进行了一些模拟:

import socketserver
from http.server import SimpleHTTPRequestHandler
import io

favicon = '<link rel="icon" href="data:;base64,=">\n'


class CustomHttpRequestHandler(SimpleHTTPRequestHandler):

    def do_GET(self):
        if self.path == '/':
            self.path = 'index.html'

        f = self.send_head()  # f is the file to send or None

        # following code will break easily. don't do this...
        content = ""
        for line in f:
            line = line.decode("utf8")
            # 'parsing' html like this is really a bad idea. don't do it...
            if "</head>" in line:
                content += favicon
            content += line

        f2 = io.BytesIO(content.encode("utf-8"))
        self.copyfile(f2, self.wfile)


if __name__ == '__main__':
    PORT = 8001
    my_server = socketserver.TCPServer(("", PORT), CustomHttpRequestHandler)
    my_server.serve_forever()

在这里,我假设您正在从当前目录提供静态文件。在将其发送给客户端之前,该<link rel="icon">标签被附加在结束<head>标签之前。当然,这很容易破裂。但是,如果您确实在生成 html 而不是提供静态文件,那么content += favicon在代码中放置该行可能很简单并且可以保存。

于 2021-01-01T10:10:29.887 回答
0

在你的内部do_GET,添加以下else if条件:

elif self.path == '/favicon.ico':
    self.send_response(200)
    self.send_header('Content-Type', 'image/x-icon')
    self.send_header('Content-Length', 0)
    self.end_headers()

这将抑制控制台错误,因为 Chrome 认为它已收到一个网站图标——即使它是一个具有正确内容类型和响应代码的 0 字节响应。

于 2021-03-30T06:01:29.937 回答