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

如何基于Flask服务器实现Web页面文件下载(Python与JavaScript方案)

搭建文件下载Web页面的两种方案

嘿,我来帮你搞定这个文件下载Web页面的需求!其实你有两种靠谱的选择——纯Python快速实现,或者结合Python+JavaScript做更友好的交互界面,我给你拆解清楚:

方案一:纯Python快速搭建(无需JavaScript)

这个方案适合快速上手,不用额外写前端交互代码,两种方式可选:

方式1:用Python内置的HTTP服务器(零代码)

这是最快的方式,连代码都不用写:

  • 打开终端,导航到你要共享文件的目录
  • 运行命令:
    • Python 3:python3 -m http.server 8000
    • Python 2:python -m SimpleHTTPServer 8000
  • 然后让用户访问 http://你的电脑IP地址:8000,就能看到目录里的所有文件,点击文件直接就能下载

缺点是界面比较简陋,是系统默认的目录列表样式,没法自定义。

方式2:用Flask搭建自定义页面(少量代码)

如果想做个好看点的自定义页面,用Flask框架很方便:

  1. 先安装Flask:pip install flask
  2. 在文件目录下创建app.py,写入以下代码:
from flask import Flask, send_from_directory, render_template
import os

app = Flask(__name__)
# 替换成你的文件存储目录,比如当前目录下的"files"文件夹
FILE_STORAGE_DIR = os.path.join(os.getcwd(), "files")

@app.route('/')
def show_file_list():
    # 获取目录下的所有文件(排除文件夹)
    file_list = [f for f in os.listdir(FILE_STORAGE_DIR) if os.path.isfile(os.path.join(FILE_STORAGE_DIR, f))]
    # 渲染前端页面并传递文件列表
    return render_template('index.html', files=file_list)

@app.route('/download/<filename>')
def download_single_file(filename):
    # 发送文件供用户下载,as_attachment=True确保浏览器触发下载而非直接打开
    return send_from_directory(FILE_STORAGE_DIR, filename, as_attachment=True)

if __name__ == '__main__':
    # host='0.0.0.0'允许同一局域网内的其他设备访问,端口可以自己改
    app.run(host='0.0.0.0', port=8000, debug=True)
  1. 创建templates文件夹,里面新建index.html:
<!DOCTYPE html>
<html>
<head>
    <title>我的文件下载站</title>
    <style>
        body { font-family: Arial, sans-serif; max-width: 800px; margin: 20px auto; }
        ul { list-style: none; padding: 0; }
        li { padding: 10px; border-bottom: 1px solid #eee; }
        a { color: #007bff; text-decoration: none; }
        a:hover { text-decoration: underline; }
    </style>
</head>
<body>
    <h1>可下载文件列表</h1>
    <ul>
        {% for file in files %}
            <li><a href="/download/{{ file }}">{{ file }}</a></li>
        {% endfor %}
    </ul>
</body>
</html>
  1. 把要共享的文件放到files文件夹里,运行python app.py,用户访问http://你的IP:8000就能看到你自定义的下载页面了。

方案二:Python后端 + JavaScript前端(增强交互体验)

如果想要更友好的用户体验——比如显示下载进度、成功/失败提示,就可以给前端加JavaScript代码。只需要修改上面的index.html,替换成下面的内容:

<!DOCTYPE html>
<html>
<head>
    <title>我的文件下载站</title>
    <style>
        body { font-family: Arial, sans-serif; max-width: 800px; margin: 20px auto; }
        .file-item { padding: 12px; border-bottom: 1px solid #eee; display: flex; align-items: center; gap: 10px; }
        .download-btn { padding: 6px 14px; background: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; }
        .download-btn:hover { background: #0056b3; }
        .progress-container { width: 200px; height: 12px; background: #f0f0f0; border-radius: 6px; display: none; }
        .progress-bar { height: 100%; background: #28a745; border-radius: 6px; width: 0%; transition: width 0.3s; }
        .status { margin-left: 10px; font-size: 14px; }
        .success { color: #28a745; }
        .error { color: #dc3545; }
    </style>
</head>
<body>
    <h1>可下载文件列表</h1>
    <div id="file-container">
        {% for file in files %}
            <div class="file-item">
                <span>{{ file }}</span>
                <button class="download-btn" data-filename="{{ file }}">立即下载</button>
                <div class="progress-container">
                    <div class="progress-bar"></div>
                </div>
                <span class="status"></span>
            </div>
        {% endfor %}
    </div>

    <script>
        // 给所有下载按钮绑定点击事件
        document.querySelectorAll('.download-btn').forEach(button => {
            button.addEventListener('click', async (e) => {
                const filename = e.target.dataset.filename;
                const progressContainer = e.target.nextElementSibling;
                const progressBar = progressContainer.querySelector('.progress-bar');
                const statusSpan = progressContainer.nextElementSibling;

                // 重置状态
                progressContainer.style.display = 'block';
                progressBar.style.width = '0%';
                statusSpan.textContent = '';
                statusSpan.className = 'status';

                try {
                    // 发起下载请求
                    const response = await fetch(`/download/${filename}`);
                    if (!response.ok) throw new Error('下载请求失败,请重试');

                    // 获取文件总大小
                    const totalSize = parseInt(response.headers.get('Content-Length'), 10);
                    let downloadedSize = 0;
                    const chunks = [];

                    // 读取数据流并更新进度
                    const reader = response.body.getReader();
                    while (true) {
                        const { done, value } = await reader.read();
                        if (done) break;
                        chunks.push(value);
                        downloadedSize += value.length;

                        // 计算并更新进度
                        const progressPercent = Math.round((downloadedSize / totalSize) * 100);
                        progressBar.style.width = `${progressPercent}%`;
                    }

                    // 生成下载链接并触发下载
                    const blob = new Blob(chunks);
                    const downloadUrl = URL.createObjectURL(blob);
                    const aTag = document.createElement('a');
                    aTag.href = downloadUrl;
                    aTag.download = filename;
                    document.body.appendChild(aTag);
                    aTag.click();
                    // 清理临时链接
                    URL.revokeObjectURL(downloadUrl);
                    document.body.removeChild(aTag);

                    // 显示成功提示
                    statusSpan.textContent = '下载完成!';
                    statusSpan.classList.add('success');
                } catch (error) {
                    // 显示错误提示
                    statusSpan.textContent = error.message;
                    statusSpan.classList.add('error');
                }
            });
        });
    </script>
</body>
</html>

这个版本里,用户点击下载按钮后会看到实时进度条,下载完成或失败都会有明确的文字提示,体验比纯静态页面好很多。

总结

  • 如果只是临时快速共享文件,用Python内置的HTTP服务器就足够;
  • 如果想要自定义页面样式,用Flask+HTML就能搞定,不需要JavaScript;
  • 如果追求更好的用户交互体验,再加上JavaScript实现进度条、状态提示这些功能,核心的文件下载逻辑还是由Python后端处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 15:52:32