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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 22:50:16