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

实现按钮同时完成文件下载与页面跳转功能

实现按钮同时完成文件下载和页面跳转

你当前的代码里,按钮点击会先触发openTab(),但紧接着表单提交会发起POST请求下载文件,这个过程会导致页面上下文变化,浏览器可能拦截新开的标签页,或者跳转逻辑被表单提交的动作打断,所以只有下载生效,跳转没执行。以下是几种可行的解决方法:

方法1:利用表单onsubmit事件控制时序

把跳转逻辑放到表单的onsubmit事件里,确保跳转先执行,同时允许表单正常提交下载:

<div class="banner">
    <h3>Download your file:<br> {{ filename }}</h3>
    <div>
        <form action="{% url 'download_pdf' %}" enctype="multipart/form-data" method="post" onsubmit="return openTab()">
            {% csrf_token %}
            <button class="btn btn-primary w-20" id="myBtn" tabindex="4">Download PDF</button>
        </form>
    </div>
</div>
<script>
function openTab() {
    // 明确指定打开新标签页
    window.open('home', '_blank');
    // 返回true允许表单提交执行下载
    return true;
}
</script>

注意:给window.open加上_blank参数避免浏览器默认行为差异;确保openTab返回true,表单才会正常提交。

方法2:用AJAX提交表单,手动控制下载和跳转

这种方式不刷新页面,能精准控制流程,避免浏览器拦截问题:

<div class="banner">
    <h3>Download your file:<br> {{ filename }}</h3>
    <div>
        {% csrf_token %}
        <button onclick="handleDownloadAndRedirect()" class="btn btn-primary w-20" id="myBtn" tabindex="4">Download PDF</button>
    </div>
</div>
<script>
function handleDownloadAndRedirect() {
    // 构建表单数据,包含CSRF令牌
    const formData = new FormData();
    const csrfToken = document.querySelector('[name="csrfmiddlewaretoken"]').value;
    formData.append('csrfmiddlewaretoken', csrfToken);

    // 发起AJAX请求
    fetch("{% url 'download_pdf' %}", {
        method: 'POST',
        body: formData
    })
    .then(response => response.blob())
    .then(blob => {
        // 手动创建下载链接触发下载
        const url = window.URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = "{{ filename }}";
        document.body.appendChild(a);
        a.click();
        window.URL.revokeObjectURL(url);
        document.body.removeChild(a);

        // 下载完成后跳转(当前页面跳转,开新标签页用window.open('home', '_blank'))
        window.location.href = 'home';
    })
    .catch(error => {
        console.error('下载失败:', error);
    });
}
</script>

需要后端正确返回文件Blob数据,同时确保CSRF令牌传递无误。

方法3:给跳转加小延迟避免拦截

如果第一种方法仍被浏览器拦截,可给跳转加短延迟,让浏览器识别为用户主动操作:

<script>
function openTab() {
    setTimeout(() => {
        window.open('home', '_blank');
    }, 100);
    return true;
}
</script>

延迟100ms足够让浏览器识别操作合法性,不会影响下载流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 02:32:39