找回密码
 立即注册
首页 程序园 问答 a标签点击不会打开新的页面下载文件

a标签点击不会打开新的页面下载文件

新程序 3 天前
  1. <template>
  2. <el-dialog v-model="downExcel.downExcelDialog" title="下载成功" width="300">
  3. <a
  4. style="color: #409eff"
  5. :href="downExcel.href"
  6. :download="downExcel.fileName"
  7. target="_blank"
  8. ref="downloadLink"
  9. >
  10. {{ downExcel.fileName }}
  11. </a>
  12. </el-dialog>
  13. </template>
  14. <script lang="ts" setup>
  15. import { reactive, ref } from "vue";
  16. const downExcel = reactive({
  17. downExcelDialog: false,
  18. href: "",
  19. fileName: "",
  20. });
  21. const downloadLink = ref();
  22. defineExpose({
  23. openDialog,
  24. });
  25. function openDialog(fileData, fileName) {
  26. const blob = new Blob([fileData], {
  27. type: "application/octet-stream",
  28. });
  29. var href = window.URL.createObjectURL(blob); // 创建下载的链接
  30. downloadLink.value = href;
  31. downExcel.href = href;
  32. downExcel.fileName = fileName;
  33. downExcel.downExcelDialog = true;
  34. }
  35. </script>
复制代码

a标签点击不会打开新的页面下载文件,已经设置了 target="_blank"

新程序 楼主
3 天前

举报

在你的代码中,<a> 标签设置了 target="_blank",但仍然没有在新页面下载文件,可能是因为 浏览器阻止了弹窗,或者 href 的生成方式有问题。以下是解决方案:

可能的原因及解决方案
1. 浏览器阻止了弹窗
某些浏览器(如 Chrome)可能会阻止 window.URL.createObjectURL() 生成的链接在新窗口打开(视为不安全弹窗)。
解决方法:改为在当前窗口下载,或者手动触发点击 <a> 标签。
2. href 生成后未立即触发下载
downExcel.downExcelDialog = true 显示弹窗后,浏览器可能不会自动处理下载。
解决方法:在 openDialog 方法中,手动触发 <a> 的点击事件。
修改后的代码
<template>
  <el-dialog v-model="downExcel.downExcelDialog" title="下载成功" width="300">
    <a
      style="color: #409eff"
      :href="downExcel.href"
      :download="downExcel.fileName"
      ref="downloadLink"
    >
      {{ downExcel.fileName }}
    </a>
  </el-dialog>
</template>

<script lang="ts" setup>
import { reactive, ref, nextTick } from "vue";

const downExcel = reactive({
  downExcelDialog: false,
  href: "",
  fileName: "",
});

const downloadLink = ref<HTMLAnchorElement>(); // 明确类型

function openDialog(fileData: BlobPart, fileName: string) {
  const blob = new Blob([fileData], {
    type: "application/octet-stream",
  });
  const href = window.URL.createObjectURL(blob);
  
  downExcel.href = href;
  downExcel.fileName = fileName;
  downExcel.downExcelDialog = true;

  // 等待弹窗渲染完成后,自动触发下载
  nextTick(() => {
    if (downloadLink.value) {
      downloadLink.value.click(); // 手动触发点击
      window.URL.revokeObjectURL(href); // 释放内存(可选)
      downExcel.downExcelDialog = false; // 关闭弹窗(可选)
    }
  });
}

defineExpose({ openDialog });
</script>
关键修改点
移除 target="_blank"

由于浏览器可能阻止弹窗,改为直接在当前页面下载。
手动触发 <a> 点击

使用 nextTick 确保 DOM 更新后,再通过 downloadLink.value.click() 触发下载。
释放内存(可选)

window.URL.revokeObjectURL(href) 可以释放 Blob 占用的内存,但如果在下载前调用会导致链接失效,所以建议在下载完成后执行(例如在 setTimeout 中延迟调用)。
替代方案(如果仍然无效)
如果浏览器仍然阻止下载,可以改用 FileSaver.js(一个专门处理文件下载的库):

npm install file-saver
然后修改代码:

import { saveAs } from "file-saver";

function openDialog(fileData: BlobPart, fileName: string) {
  const blob = new Blob([fileData], { type: "application/octet-stream" });
  saveAs(blob, fileName); // 直接下载,无需 <a> 标签
  downExcel.downExcelDialog = true; // 仅显示提示(可选)
}
总结
推荐方案:手动触发 <a> 点击(如修改后的代码)。
备选方案:使用 FileSaver.js 直接下载。
注意事项:浏览器可能会拦截 Blob 链接的弹窗,因此避免依赖 target="_blank"。
您需要登录后才可以回帖 登录 | 立即注册