Python自定义HTTP服务器将HTML显示为文本而非渲染的问题求助
问题修复方案
你的Python HTTP服务器存在几个关键问题,导致浏览器把HTML当作纯文本渲染:
- 响应流程顺序错误:必须先发送状态码(
send_response),再设置响应头(send_header),最后结束头(end_headers)。你的代码顺序完全颠倒,导致响应格式不合法。 - 重复设置Content-Type:多次设置同一个
content-type头,最终生效的是最后一个text/css,浏览器会把HTML文件当作CSS解析,自然显示异常。 - 未根据文件后缀匹配正确MIME类型:所有文件都用同一个类型,无法区分HTML、JS、CSS等不同资源。
- 异常处理不规范:捕获所有异常但未正确构造404响应,也没有关闭文件的逻辑。
- 文件打开未指定编码:可能导致中文等非ASCII字符渲染乱码。
修复后的完整代码:
from http.server import HTTPServer, BaseHTTPRequestHandler import os from urllib.parse import unquote # 定义常见文件对应的MIME类型 MIME_TYPES = { '.html': 'text/html; charset=utf-8', '.css': 'text/css; charset=utf-8', '.js': 'text/javascript; charset=utf-8', '.txt': 'text/plain; charset=utf-8', '.png': 'image/png', '.jpg': 'image/jpeg', '.gif': 'image/gif' } HOST = "localhost" PORT = 7800 class FeedSpeedServer(BaseHTTPRequestHandler): def do_GET(self): # 处理根路径,指向index.html path = unquote(self.path) if path == "/": path = '/index.html' # 拼接文件路径,防止路径遍历 file_path = os.path.join(os.getcwd(), path.lstrip('/')) # 检查文件是否存在且是文件(不是目录) if os.path.exists(file_path) and os.path.isfile(file_path): try: # 获取文件后缀,匹配MIME类型 ext = os.path.splitext(file_path)[1].lower() content_type = MIME_TYPES.get(ext, 'application/octet-stream') # 正确的响应流程:状态码 -> 响应头 -> 结束头 -> 发送内容 self.send_response(200) self.send_header("Content-Type", content_type) self.end_headers() # 以二进制模式读取文件,避免编码问题 with open(file_path, 'rb') as f: self.wfile.write(f.read()) except Exception as e: self.send_error(500, f"Server Error: {str(e)}") else: # 404响应 self.send_response(404) self.send_header("Content-Type", "text/plain; charset=utf-8") self.end_headers() self.wfile.write(b"404 - File Not Found") httpd = HTTPServer((HOST, PORT), FeedSpeedServer) print(f"Server running at http://{HOST}:{PORT}") httpd.serve_forever()
关键修改说明:
- 修正响应流程:严格按照
send_response→send_header→end_headers→ 发送内容的顺序执行。 - 动态匹配MIME类型:通过文件后缀从预定义的
MIME_TYPES字典中获取对应类型,确保不同资源被正确识别。 - 安全处理文件路径:使用
unquote解码URL,并用os.path.join拼接路径,防止路径遍历攻击;同时检查文件是否存在且为普通文件。 - 规范异常处理:分别处理文件存在但读取失败(返回500)和文件不存在(返回404)的情况,且用
with语句自动关闭文件。 - 二进制读取文件:避免文本编码问题,特别是图片等二进制资源必须用二进制模式读取。
内容的提问来源于stack exchange,提问作者Lo_
相关产品推荐
相关产品推荐

