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

JavaScript:如何在文件下载前后正确触发函数?

解决文件下载时fadeIn/fadeOut时机不对的问题

这个问题的核心在于document.location = "/Employee/Data?Type=CSV"是异步触发下载的——浏览器会立即发送请求,但不会等待文件下载完成就继续执行后面的fn_fadeOutWaiting()。小文件下载速度快,刚好能跟上代码执行节奏,大文件就会出现等待动画提前消失的情况。

这里有几个靠谱的解决方案,按推荐程度排序:

方案1:使用Fetch API + Blob 创建下载链接

这种方法可以直接监听文件下载完成的事件,完美控制fade的时机:

// 先显示等待动画
fn_fadeInWaiting();

// 用Fetch请求文件
fetch("/Employee/Data?Type=CSV")
  .then(response => {
    // 确保请求成功
    if (!response.ok) throw new Error("下载请求失败");
    return response.blob();
  })
  .then(blob => {
    // 创建下载链接
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    // 设置文件名(如果后端返回了Content-Disposition,也可以从header里解析)
    a.download = 'employee_data.csv';
    document.body.appendChild(a);
    a.click();
    // 清理资源
    URL.revokeObjectURL(url);
    document.body.removeChild(a);
    // 下载完成,隐藏等待动画
    fn_fadeOutWaiting();
  })
  .catch(error => {
    console.error("下载出错:", error);
    // 出错也要隐藏动画,避免一直显示
    fn_fadeOutWaiting();
  });

方案2:使用XMLHttpRequest(兼容旧浏览器)

如果需要兼容不支持Fetch的旧浏览器,可以用XHR:

fn_fadeInWaiting();

const xhr = new XMLHttpRequest();
xhr.open('GET', "/Employee/Data?Type=CSV", true);
xhr.responseType = 'blob';

xhr.onload = function() {
  if (xhr.status === 200) {
    const blob = xhr.response;
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'employee_data.csv';
    document.body.appendChild(a);
    a.click();
    URL.revokeObjectURL(url);
    document.body.removeChild(a);
    fn_fadeOutWaiting();
  } else {
    console.error("下载请求失败,状态码:", xhr.status);
    fn_fadeOutWaiting();
  }
};

xhr.onerror = function() {
  console.error("下载出错");
  fn_fadeOutWaiting();
};

xhr.send();

额外优化:动态获取文件名

如果后端返回的Content-Disposition header里包含文件名,可以通过解析header来动态获取,不用硬编码:

const disposition = response.headers.get('Content-Disposition');
const filenameMatch = disposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
const filename = filenameMatch ? filenameMatch[1].replace(/['"]/g, '') : 'employee_data.csv';

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:01:42