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

如何在Python的http.server中编码二进制响应?发送媒体文件报错求助

解决Python http.server发送二进制文件的UnicodeDecodeError问题

问题原因

出现UnicodeDecodeError是因为打开二进制文件(图片、视频等)时使用了文本模式("r"),文本模式会自动尝试用UTF-8解码文件内容,而二进制文件的字节不符合UTF-8编码规则,导致解码失败。另外代码中还有两个小问题:

  • mimetypes.guess_type()返回的是元组(如('image/jpeg', None)),直接转字符串会导致Content-Type头格式错误
  • 对二进制文件内容做了多余的字符串转换,进一步引发编码问题

修复后的代码

from http.server import BaseHTTPRequestHandler, HTTPServer
import os.path
import mimetypes

# 读取配置(原代码保留,若不需要可删除)
config = open("config.txt", "r")
configlist = config.read().split("__")

hostName = "0.0.0.0"
serverPort = 8080

class MyServer(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == "/":
            # 文本文件用文本模式打开并指定编码
            with open("srvf/index.html", "r", encoding="utf-8") as mp:
                self.send_response(200)
                self.send_header("Content-type", "text/html")
                self.end_headers()
                self.wfile.write(mp.read().encode("utf-8"))
        elif os.path.exists("srvf" + self.path):
            file_path = "srvf" + self.path
            # 二进制文件用rb模式打开
            with open(file_path, "rb") as f:
                self.send_response(200)
                # 正确处理MIME类型,取元组第一个元素,默认用二进制流类型
                mime_type, _ = mimetypes.guess_type(file_path)
                content_type = mime_type or "application/octet-stream"
                self.send_header("Content-type", content_type)
                self.end_headers()
                # 直接写入二进制数据,无需转换
                self.wfile.write(f.read())
        else:
            with open("error.html", "r", encoding="utf-8") as a:
                self.send_response(404)
                self.send_header("Content-type", "text/html")
                self.end_headers()
                self.wfile.write(a.read().encode("utf-8"))
                print(f"error 404 on {self.path}")

if __name__ == "__main__":        
    webServer = HTTPServer((hostName, serverPort), MyServer)
    print(f"Server started http://{hostName}:{serverPort}")

    try:
        webServer.serve_forever()
    except KeyboardInterrupt:
        pass

    webServer.server_close()
    print("Server stopped.")

关键修改点

  • 打开文件时区分模式:文本文件(如html)用"r"并指定编码,二进制文件用"rb"模式
  • 正确解析mimetypes.guess_type()的结果,提取有效的MIME类型
  • 二进制文件直接读取字节并写入响应,避免不必要的字符串转换

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 05:28:09