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

如何使用Flask实现点击文件链接在网页查看文件内容?

问题分析与解决方案

你的代码存在几个关键问题,导致无法实现点击查看文件内容的功能:

  • 直接使用本地文件路径作为链接href,浏览器出于安全限制无法直接访问本地文件
  • HTML结构拼接混乱,重复初始化、错误闭合标签,导致页面结构错乱
  • 没有对应路由处理文件内容的请求

以下是修正后的完整代码:

from flask import Flask, render_template_string, abort
import os
from urllib.parse import quote

app = Flask(__name__)
BASE_FOLDER = "/home/user/"

# 生成安全的文件路径,防止目录遍历攻击
def get_safe_path(file_path):
    full_path = os.path.abspath(os.path.join(BASE_FOLDER, file_path.lstrip('/')))
    if not full_path.startswith(os.path.abspath(BASE_FOLDER)):
        return None
    return full_path

@app.route("/")
def mostrar_subcarpeta():
    def generate_folder_html(root, depth=0):
        html = ""
        # 获取当前文件夹名称
        folder_name = os.path.basename(root) if root != BASE_FOLDER else "根目录"
        # 缩进展示层级
        html += f"<div style='margin-left: {depth*20}px;'>"
        html += f"<strong>{folder_name}</strong>"
        html += "<ul>"
        
        # 先处理文件
        for filename in os.listdir(root):
            file_path = os.path.join(root, filename)
            if os.path.isfile(file_path):
                # 生成相对路径用于路由
                rel_path = os.path.relpath(file_path, BASE_FOLDER)
                encoded_rel_path = quote(rel_path)
                html += f"<li><a href='/view/{encoded_rel_path}'>{filename}</a></li>"
        
        # 递归处理子文件夹
        for folder in os.listdir(root):
            folder_path = os.path.join(root, folder)
            if os.path.isdir(folder_path):
                html += generate_folder_html(folder_path, depth+1)
        
        html += "</ul></div>"
        return html

    return render_template_string("""
        <!DOCTYPE html>
        <html>
        <head>
            <title>文件浏览器</title>
        </head>
        <body>
            {{ folder_html|safe }}
        </body>
        </html>
    """, folder_html=generate_folder_html(BASE_FOLDER))

@app.route("/view/<path:file_path>")
def view_file(file_path):
    safe_path = get_safe_path(file_path)
    if not safe_path or not os.path.isfile(safe_path):
        abort(404)
    
    # 根据文件类型读取内容,这里处理文本文件,其他类型可扩展
    try:
        with open(safe_path, 'r', encoding='utf-8') as f:
            content = f.read()
        return render_template_string("""
            <!DOCTYPE html>
            <html>
            <head>
                <title>查看文件: {{ filename }}</title>
                <style>
                    pre {
                        background: #f4f4f4;
                        padding: 15px;
                        overflow-x: auto;
                    }
                </style>
            </head>
            <body>
                <h3>{{ filename }}</h3>
                <pre>{{ content }}</pre>
                <p><a href='/'>返回文件列表</a></p>
            </body>
            </html>
        """, filename=os.path.basename(safe_path), content=content)
    except UnicodeDecodeError:
        return "<h3>无法预览此文件:非文本格式</h3><p><a href='/'>返回文件列表</a></p>"

if __name__ == "__main__":
    app.run(debug=True)

关键改进点:

  • 安全路径处理:通过get_safe_path函数限制访问范围在指定目录内,防止恶意目录遍历
  • 正确路由链接:生成Flask内部路由/view/来处理文件内容请求,不再直接使用本地路径
  • 清晰的层级展示:递归生成带缩进的文件夹和文件结构,页面更易读
  • 文本文件预览:支持UTF-8文本文件的内容展示,非文本文件给出提示
  • 规范HTML结构:使用Jinja2模板渲染,避免手动拼接HTML的错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 01:05:33