问题描述
在 python 3.8 上,我使用模块 http.server 中的 BaseHTTPRequestHandler 和 HTTPServer 为我的学生创建了一个极简的 python 服务器
当我去服务器上的url时,在浏览器调试工具中看到两个http请求:
我想阻止第二个请求(对于网站图标)。我的问题是:使用“BaseHTTPRequestHandler”和“HTTPServer”类是否可以自定义生成页面的标题?我正在寻找一种方法来添加这样的空图标:<link rel="icon" href="data:;base64,=">
(https://stackoverflow.com/a/13416784/2137454)
解决方法
这显然是可能的。毕竟,您可以完全控制服务器向客户端发送的内容。但是,我认为您不应该这样做。只需提供那个烦人的小文件 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()
要完成这项工作,您需要做的就是在文件夹 static
中放置一个 png 文件并将其命名为 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(("",CustomHttpRequestHandler)
my_server.serve_forever()
这里我假设您正在提供当前目录中的静态文件。在将其发送给客户端之前,<link rel="icon">
标记会附加在结束 <head>
标记之前。当然,这很容易破裂。
但是,如果您确实要生成 html 而不是提供静态文件,则在代码中放置 content += favicon
行可能很简单且省钱。
在您的 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 字节响应。