Flask中如何统一父文件夹路径加载多资源并优化路由实现
解决方案
1. 先配置资源访问路由
首先给folder3的资源做一个统一的访问入口,让所有图片、PDF都能通过固定URL前缀直接访问,避免前端路径处理:
from flask import Flask, send_from_directory, url_for import os app = Flask(__name__) DATA_ROOT = "data" # 服务folder3下的所有资源 @app.route("/resources/<path:file_path>") def serve_resources(file_path): # 防止目录遍历攻击 safe_path = os.path.normpath(file_path) if ".." in safe_path: return "非法路径", 403 return send_from_directory(os.path.join(DATA_ROOT, "folder3"), safe_path)
2. 实现单路由返回菜单+内容+处理后的资源路径
创建一个聚合路由,一次性读取菜单XML、内容XML,同时用XML解析(而非正则)替换资源路径为可直接访问的URL:
import xmltodict @app.route("/api/full-content") def get_full_content(): # 1. 读取并解析菜单XML menu_path = os.path.join(DATA_ROOT, "folder1", "menu.xml") with open(menu_path, "r", encoding="utf-8") as f: menu_data = xmltodict.parse(f.read()) # 2. 读取对应内容XML并处理资源路径 contents = [] # 假设菜单结构为 <menu><item link="../folder2/xxx.xml">...</item></menu> for menu_item in menu_data["menu"]["item"]: # 转换内容XML的相对路径为绝对路径 content_rel_path = menu_item["link"] content_abs_path = os.path.join(DATA_ROOT, os.path.normpath(content_rel_path)) with open(content_abs_path, "r", encoding="utf-8") as f: content_data = xmltodict.parse(f.read()) # 递归替换内容里的资源路径(src/href字段) def replace_paths(obj): if isinstance(obj, dict): for key, val in obj.items(): if key in ["src", "href"] and isinstance(val, str) and "../folder3/" in val: # 提取folder3后的资源路径,生成可访问URL resource_path = val.split("../folder3/")[-1] obj[key] = url_for("serve_resources", file_path=resource_path, _external=True) elif isinstance(val, (dict, list)): replace_paths(val) elif isinstance(obj, list): for item in obj: replace_paths(item) replace_paths(content_data) contents.append({ "menu_title": menu_item["title"], "content": content_data }) # 3. 返回聚合数据 return { "menu": menu_data["menu"], "contents": contents }
3. 前端调用
前端只需一次Fetch请求即可拿到所有数据,内容里的图片、PDF路径已经是直接可访问的URL,无需额外处理:
fetch('/api/full-content') .then(res => res.json()) .then(data => { // 直接渲染菜单和内容,资源路径可直接使用 console.log(data.menu, data.contents); });
关键说明
- 用XML解析库(
xmltodict)替代正则,路径处理更精准、维护性更强 - 资源路由通过
send_from_directory安全返回文件,同时做了目录遍历防护 - 用
url_for生成绝对URL,适配不同部署环境的域名/端口
内容的提问来源于stack exchange,提问作者Mario
相关产品推荐
相关产品推荐

