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

VueJS结合GraphQL实现PDF下载时首次点击触发网络错误如何解决

问题根本原因

当前代码的核心问题是异步逻辑处理错误:downloadFile 内部的axios请求是异步执行的,你使用固定1秒等待的方式完全不可靠:

  • 首次点击时请求还没返回结果,this.file_info 还没有被赋值,就调用了下载逻辑,自然报错
  • 文件越大,接口返回耗时越长,固定等待的时间就越难匹配请求耗时,所以大文件需要多次点击才能碰巧赶上请求完成的时间点

修复方案

1. 核心逻辑调整

  • 让downloadFile返回axios的Promise实例,这样可以用await精准等待请求完成,不用固定时长等待
  • 增加下载中状态锁,避免用户重复点击触发多次请求
  • 修正下载的MIME类型,PDF文件应该用application/pdf而非text/plain,避免下载后文件无法正常打开
  • 增加错误捕获逻辑,接口出错时可以直接给用户提示,不用等超时

2. 修改后的完整代码

// 提前在data中初始化状态:isDownloading: false, download_file_name: ''
sleep(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
},

// 改为返回Promise实例
downloadFile() {
  const vm = this;
  vm.count ++;
  return axios.post("http://0.0.0.0/graphql", {
    query: `mutation download_doc($object_path:String!) {
      download_doc(object_path:$object_path) {
        file_name
        encoded_file
      }
    }`, 
    variables : {
      object_path: this.object_path
    }
  })
  .then(response => {
    vm.file_info = response.data.data.download_doc.encoded_file
    // 存储后端返回的原始文件名,比直接用object_path更合理
    vm.download_file_name = response.data.data.download_doc.file_name
  })
  .catch(err => {
    console.error('下载接口请求失败', err)
    alert('文件下载失败,请稍后重试')
    throw err
  })
},

downloadBase64File(base64Data, fileName) {
  // 修正PDF对应的MIME类型
  const linkSource = `data:application/pdf;base64,${base64Data}`;
  const downloadLink = document.createElement("a");
  downloadLink.href = linkSource;
  downloadLink.download = fileName;
  downloadLink.click();
  // 移除创建的DOM节点,避免内存泄漏
  downloadLink.remove()
},

async download() {
  // 重复点击拦截
  if(this.isDownloading) return
  this.isDownloading = true
  try {
    // 等待请求真正完成,不需要固定时长盲等
    await this.downloadFile();
    this.downloadBase64File(this.file_info, this.download_file_name || this.object_path);
    await this.sleep(1000);
    if (this.count >= 2) {
      this.clearForm()
    }
  } catch(err) {
    console.error('下载流程出错', err)
  } finally {
    // 无论成功失败都重置下载状态
    this.isDownloading = false
  }
}

3. 额外优化建议

如果你的PDF文件体积较大,base64编码会让文件体积膨胀30%左右,传输效率很低。可以让后端直接返回文件流,前端通过blob方式下载,性能会好很多,也不会出现大文件base64解析失败的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 02:24:02