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

网页文件下载脚本间歇性报错:大文件Fetch失败问题排查

问题分析与修复方案

你的脚本在大文件下载场景下出现的报错,主要和fetch默认配置不适合大文件传输、错误处理缺失、资源未及时释放有关,以下是针对性的修复方案:

原脚本存在的问题

  • 大文件下载时未设置超时,网络不稳定时容易触发请求失败
  • Fetch的错误处理不完整,仅捕获了请求阶段的错误,blob转换等后续步骤未处理
  • 下载完成后未释放window.URL.createObjectURL创建的对象URL,长期运行可能导致内存泄漏
  • 遍历版本列表时未在找到匹配项后终止循环,造成不必要的性能消耗
  • 按钮状态更新仅在成功时处理,失败时没有反馈

修复后的完整代码

const dwnldBtn = document.getElementById("downloadButton");
let filename = "";
let ext = "";
const title = document.getElementsByTagName("title")[0].innerText.split(" ");
const anchor = document.createElement("a");
anchor.style.display = "none";
document.body.appendChild(anchor);

async function FetchTheRest() {
  try {
    // 配置大文件下载的超时和中断,支持主动终止请求
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), 300000); // 5分钟超时,可按需调整

    const res = await fetch(`https://pathToFile`, {
      signal: controller.signal,
      headers: { "Accept": "*/*" }
    });

    clearTimeout(timeoutId);

    if (!res.ok) {
      throw new Error(`请求失败: ${res.status} ${res.statusText}`);
    }

    const blob = await res.blob();
    const url = window.URL.createObjectURL(blob);
    
    anchor.href = url;
    anchor.download = filename;
    dwnldBtn.style.backgroundColor = "#00ff00";
    dwnldBtn.disabled = false;

    // 下载完成后延迟释放URL资源,避免触发下载时资源已被回收
    anchor.addEventListener("click", () => {
      setTimeout(() => window.URL.revokeObjectURL(url), 1000);
    });
  } catch (err) {
    console.error("下载失败:", err);
    dwnldBtn.style.backgroundColor = "#ff0000";
    dwnldBtn.disabled = false;
    alert(`文件下载失败,请稍后重试: ${err.message}`);
  }
}

async function getEXT() {
  try {
    const res = await fetch("https://pathToFile.json");
    if (!res.ok) {
      throw new Error(`获取版本信息失败: ${res.status}`);
    }
    const versionData = await res.json();
    
    // 找到匹配版本后立即终止循环,提升效率
    const matchedVersion = versionData.versions.find(version => version.version === title[4]);
    if (matchedVersion) {
      ext = matchedVersion.ext;
      filename = `DSGM ${title[4]}.${ext}`;
      document.getElementById("NameOfFile").textContent = filename;
      dwnldBtn.disabled = false;
      FetchTheRest();
    } else {
      throw new Error("未找到匹配的版本信息");
    }
  } catch (err) {
    console.error("版本信息获取失败:", err);
    dwnldBtn.style.backgroundColor = "#ff0000";
    alert(`无法获取文件信息,请稍后重试: ${err.message}`);
  }
}

// 初始化按钮状态,避免用户提前点击
dwnldBtn.disabled = true;
dwnldBtn.addEventListener("click", () => {
  if (anchor.href) {
    anchor.click();
  } else {
    alert("文件尚未准备好,请稍候");
  }
});

getEXT();

关键修改说明

  1. 添加请求超时与中断机制
    使用AbortController实现请求超时中断,避免大文件下载时因网络卡顿导致无响应的请求长期挂起,超时时间可根据文件大小调整。

  2. 完善全流程错误处理
    所有异步操作都用try/catch包裹,覆盖请求发起、JSON解析、blob转换全流程;同时检查响应状态码res.ok,即使返回200状态码,若实际请求异常也能捕获。

  3. 优化资源管理
    提前创建并隐藏anchor元素,避免DOM操作时机问题;下载完成后通过window.URL.revokeObjectURL释放blob URL,防止内存泄漏。

  4. 性能与体验优化

    • 用Array.find()替代forEach遍历版本列表,找到匹配项后立即终止循环
    • 初始化时禁用下载按钮,避免用户在文件未准备好时点击;点击时先判断文件状态,给出对应提示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 12:00:21