Python http.server 如何从当前工作目录的上级目录提供HTML文件
解决Python http.server访问上级目录文件的404问题
嘿,你猜的完全没错——SimpleHTTPRequestHandler确实内置了目录遍历防护机制,它会自动解析掉路径里的../这类相对上级目录的标识,所以你直接用../manage.html或者绝对路径都会被它处理掉,导致找不到文件返回404。既然你是本地使用不在乎安全性,这里有几种可行的解决方案:
方案一:直接在do_GET中读取并返回目标文件
这种方式最直接,绕开父类的路径处理逻辑,自己手动读取上级目录的文件并发送响应:
from http.server import SimpleHTTPRequestHandler import os class Server(SimpleHTTPRequestHandler): def do_GET(self): # 处理/manage请求 if self.path == "/manage": # 构造上级目录中manage.html的绝对路径 target_file = os.path.abspath(os.path.join(os.getcwd(), "..", "manage.html")) try: # 以二进制模式打开文件 with open(target_file, 'rb') as f: # 发送响应头 self.send_response(200) self.send_header('Content-Type', 'text/html') self.end_headers() # 写入文件内容到响应 self.wfile.write(f.read()) return except FileNotFoundError: # 如果文件不存在,返回404 self.send_error(404, "Requested file not found") return # 其他请求沿用默认处理逻辑 super().do_GET(self)
方案二:重写translate_path方法,允许访问上级目录
SimpleHTTPRequestHandler的translate_path方法负责将请求路径转换为本地文件路径,默认会限制在当前服务器目录内。我们可以重写这个方法,让它允许访问上级目录:
仅针对manage.html的特殊处理
如果只需要访问上级目录的manage.html,可以针对性修改:
from http.server import SimpleHTTPRequestHandler import os class Server(SimpleHTTPRequestHandler): def translate_path(self, path): # 针对/manage.html的请求,直接指向上级目录的文件 if path == "/manage.html": return os.path.abspath(os.path.join(os.getcwd(), "..", "manage.html")) # 其他请求依旧使用默认路径转换逻辑 return super().translate_path(path) def do_GET(self): if self.path == "/manage": self.send_response(200) self.path = "/manage.html" return super().do_GET(self) else: super().do_GET(self)
允许整个上级目录的访问
如果你需要从上级目录提供多个文件,可以把服务器根目录直接设为上级目录:
from http.server import SimpleHTTPRequestHandler import os class Server(SimpleHTTPRequestHandler): def translate_path(self, path): # 去掉请求路径中的查询参数和锚点 path = path.split('?', 1)[0] path = path.split('#', 1)[0] # 将服务器根目录设置为当前脚本目录的上级目录 root_dir = os.path.abspath(os.path.join(os.getcwd(), "..")) # 拼接请求路径到根目录 return os.path.normpath(os.path.join(root_dir, path.lstrip('/'))) def do_GET(self): if self.path == "/manage": self.path = "/manage.html" return super().do_GET(self) else: super().do_GET(self)
为什么原来的方法不行?
原来的代码中,当你设置self.path = "../manage.html"后,SimpleHTTPRequestHandler的默认translate_path方法会调用os.path.normpath解析路径,把../去掉,最终指向当前服务器目录下的manage.html,而这个文件已经被移到上级目录了,所以自然返回404错误。
内容的提问来源于stack exchange,提问作者VerteronParticle
相关产品推荐
相关产品推荐

