You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()

关键修改说明:

  1. 修正响应流程:严格按照send_response → send_header → end_headers → 发送内容的顺序执行。
  2. 动态匹配MIME类型:通过文件后缀从预定义的MIME_TYPES字典中获取对应类型,确保不同资源被正确识别。
  3. 安全处理文件路径:使用unquote解码URL,并用os.path.join拼接路径,防止路径遍历攻击;同时检查文件是否存在且为普通文件。
  4. 规范异常处理:分别处理文件存在但读取失败(返回500)和文件不存在(返回404)的情况,且用with语句自动关闭文件。
  5. 二进制读取文件:避免文本编码问题,特别是图片等二进制资源必须用二进制模式读取。

内容的提问来源于stack exchange,提问作者Lo_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 16:18:34