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

如何实现Flask中使用send_file下载文件后自动重定向至新页面?

解决点击下载链接同时触发下载和页面跳转的问题

我来帮你搞定这个问题!你遇到的核心矛盾是:HTTP响应一次只能返回一个结果(要么是下载文件,要么是页面重定向),所以后端没法同时完成这两个动作。我们得换个思路,让前端JavaScript来处理这两个并行的操作,同时还要做好防重复点击的处理。

问题根源分析

你的原代码里,send_file和redirect都是返回HTTP响应的操作,浏览器只能接收其中一个,所以没法同时触发下载和跳转。而且直接用<a>标签加target="_blank"的方式,也没法很好地控制跳转时机和禁用按钮。

具体解决方案

我们分两步修改:前端处理双动作触发+防重复点击,后端优化多用户隔离。

1. 修改前端HTML(conversion_complete.html)

用JavaScript监听按钮点击事件,先触发下载请求,再跳转页面,同时立即禁用按钮防止重复点击:

<html>
<body>
<h1>Conversion Complete</h1>
<button id="downloadBtn" class='btn btn-default'>Download!</button>

<script>
document.getElementById('downloadBtn').addEventListener('click', function() {
    // 第一步:触发文件下载
    const downloadTrigger = document.createElement('a');
    downloadTrigger.href = '/download/';
    downloadTrigger.download = ''; // 让浏览器使用后端返回的文件名
    downloadTrigger.style.display = 'none';
    document.body.appendChild(downloadTrigger);
    downloadTrigger.click();
    document.body.removeChild(downloadTrigger);

    // 第二步:禁用按钮,防止重复点击
    this.disabled = true;
    this.textContent = 'Downloading...';

    // 第三步:延迟跳转,确保下载请求已发送到后端
    setTimeout(() => {
        window.location.href = '/'; // 这里可以改成你想要跳转的目标页面,比如首页
    }, 600);
});
</script>
</body>
</html>

2. 优化后端代码(解决多用户冲突问题)

原代码里把下载文件的信息存在download_video函数的属性里,这会导致多个用户同时使用时互相覆盖。我们改用session来存储每个用户的下载信息,同时下载完成后清理文件和session:

from flask import Flask, render_template, redirect, url_for, session, request, flash, send_file
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, BooleanField
from pytube import YouTube
import os
import random, string
import re

app = Flask(__name__)
app.config['SECRET_KEY'] = 'mysecretkey'

class url_form(FlaskForm):
    link = StringField('Enter link of YouTube video you would like to convert...')
    audio = BooleanField('Audio Only')
    submit = SubmitField('Convert')

def download_video(link, just_audio):
    yt = YouTube(link)
    download_path = 'conversions/'
    # 创建conversions目录如果不存在
    os.makedirs(download_path, exist_ok=True)
    
    if just_audio:
        stream = yt.streams.filter(only_audio=True).first()
    else:
        stream = yt.streams.filter(adaptive=True).first()
    
    title = yt.title
    clean_title = re.sub('[^a-zA-Z0-9 \n\.]', '', title)
    thumbnail = yt.thumbnail_url
    file_path = stream.download(filename=clean_title, output_path=download_path)
    
    # 返回下载信息字典,存在session中
    return {
        'title': title,
        'clean_title': clean_title,
        'thumbnail': thumbnail,
        'file_path': file_path
    }

@app.route('/', methods=['GET', 'POST'])
def index():
    form = url_form()
    if form.validate_on_submit():
        link = form.link.data
        just_audio = form.audio.data
        download_info = download_video(link, just_audio)
        # 把当前用户的下载信息存入session
        session['download_info'] = download_info
        return redirect(url_for('conversion_complete'))
    return render_template('index.html', form=form)

@app.route('/conversion_complete')
def conversion_complete():
    # 如果session里没有下载信息,直接跳回首页
    if not session.get('download_info'):
        flash('No conversion found!')
        return redirect(url_for('index'))
    return render_template('conversion_complete.html')

@app.route('/download/')
def download():
    download_info = session.get('download_info')
    if not download_info:
        flash('No download available!')
        return redirect(url_for('index'))
    
    file_path = download_info['file_path']
    filename = download_info['clean_title'] + '.mp4'
    
    # 下载完成后清理文件和session
    def cleanup():
        if os.path.exists(file_path):
            os.remove(file_path)
        session.pop('download_info', None)
    
    return send_file(
        file_path,
        attachment_filename=filename,
        as_attachment=True,
        after_send=cleanup
    )

方案说明

  • 前端逻辑:通过创建隐藏的<a>标签触发下载,避免页面跳转中断下载请求;立即禁用按钮彻底防止重复点击;延迟跳转确保下载请求已经发送到后端。
  • 后端优化:用session隔离每个用户的下载信息,避免多用户冲突;下载完成后自动删除文件和session中的记录,节省服务器空间同时防止重复下载。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 20:22:44