vue 前端通过后端返回的文件流,直接在浏览器下载文件(js)

前端JS接口调用及图片下载问题

接口调用成功,返回的数据是这种样子(有两种数据)

前端js:

aa(){
        let param = { Id: val.val.MongodbIds, FileName: val.val.FileName };
        this.$luleApi
          .DownloadFileById(param)
          .then((res) => {
           //获取文件名称 三种写法,主要是看后端给你返回的,我这里就用第一种
            const fileName = JSON.parse(res.config.data).FileName; 
//const fileName = window.decodeURI(decodeURIComponent(decodeURI(res.headers['content-disposition'].split(`''`) [1])));
           //const fileName= res.headers['content-disposition'].split('filename=')[1]
            const url = window.URL.createObjectURL(new Blob([res.data])); // 创建一个Blob对象,包含响应的数据(文件内容)。
            const link = document.createElement("a"); // // 创建一个<a>元素,用于触发下载。
            link.href = url; // 设置<a>元素的href属性为Blob对象的URL。 
            link.setAttribute("download", fileName); // 设置<a>元素的download属性为文件名,这样浏览器就知道下载的文件应该叫什么名字。 
            document.body.appendChild(link);// 将<a>元素添加到文档的body中(虽然这一步不是必需的,但可以避免在某些浏览器中出现问题)。  
            link.click(); // 触发<a>元素的点击事件,开始下载。  
            document.body.removeChild(link);  // 下载完成后,从文档中移除<a>元素。
          })
          .catch((err) => {});
}

ps: 如果根据上述操作之后,下载的图片无法预览,可以修改以下位置

api.js**********************
//旧写法 
//DownloadFileById: (params) => {
   // return service.post("api/GridFS/DownloadFileById", params);
 // },

  // 修改之后的
  DownloadFileById: (config, params) => {
    return service.post("api/GridFS/DownloadFileById", params, config);
  },


a.vue

修改为:
Download(data) {
      let param = {
        Id: "67455ac4fe011820f0c1c8a6",
        FileName: "病人详情-实时监测(1).png"
      };

      this.$luleApi
        .DownloadFileById({ responseType: "arraybuffer" }, param)
        .then((res) => {
          console.log('下载=====', res);

          const fileName = JSON.parse(res.config.data).FileName;
          const blob = new Blob([res.data], { type: "application/octet-stream" });
          debugger
          const url = URL.createObjectURL(blob);
           console.log(url, "下载1");
          const link = document.createElement("a");
          link.href = url;
          link.download = fileName; 
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
          URL.recycleObjectURL(url);
        })
        .catch((err) => { });
    },

Vue3 项目中实现后端下载文件并传递到前端浏览器展示或下载,通常涉及以下几个关键步骤: ### 文件下载的实现方式 当后端返回的是文件流(如 `Blob` 类型)时,前端需要将该文件流转换为可下载文件直接展示在页面中。常见的做法是通过 `axios` 或 `fetch` 请求后端接口,并设置 `responseType: 'blob'`,确保浏览器能正确解析二进制数据。 ```javascript import axios from 'axios'; const downloadFile = async (fileId) => { try { const response = await axios.get(`/api/files/${fileId}`, { responseType: 'blob', // 确保响应内容为 Blob 类型 }); const url = window.URL.createObjectURL(new Blob([response.data])); const link = document.createElement('a'); link.href = url; link.setAttribute('download', 'example.pdf'); // 设置下载文件名 document.body.appendChild(link); link.click(); link.remove(); } catch (error) { console.error('文件下载失败:', error); } }; ``` 如果后端返回的是 Base64 编码的文件内容,可以通过 `atob` 解码后生成 `Blob` 并创建下载链接。 ```javascript const downloadBase64File = (base64Data, fileName, mimeType = 'application/pdf') => { const byteCharacters = atob(base64Data); const byteNumbers = new Array(byteCharacters.length); for (let i = 0; i < byteCharacters.length; i++) { byteNumbers[i] = byteCharacters.charCodeAt(i); } const byteArray = new Uint8Array(byteNumbers); const blob = new Blob([byteArray], { type: mimeType }); const url = window.URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.setAttribute('download', fileName); document.body.appendChild(link); link.click(); link.remove(); }; ``` ### 在页面中展示文件 若需要在页面中直接展示文件(如 PDF 或图片),可以使用 `URL.createObjectURL` 创建临时链接并将其赋值给 `<iframe>` 或 `<img>` 标签。 ```javascript const previewFile = async (fileId) => { try { const response = await axios.get(`/api/files/${fileId}`, { responseType: 'blob', }); const url = window.URL.createObjectURL(new Blob([response.data])); const preview = document.getElementById('file-preview'); preview.src = url; } catch (error) { console.error('文件预览失败:', error); } }; ``` 对应的 HTML 部分: ```html <iframe id="file-preview" style="width: 100%; height: 600px;"></iframe> ``` ### 文件上传与下载的接口设计 在前后端交互中,后端应提供统一的文件下载接口,例如 `/api/files/:id`,并通过 HTTP 头部指定 `Content-Type` 为 `application/octet-stream` 或具体文件类型(如 `application/pdf`),以确保浏览器能正确识别文件格式 [^2]。 ### Vue3 中的异步处理与错误捕获 在 Vue3 中使用 `async/await` 语法时,必须结合 `try/catch` 结构来捕获异常,避免 Promise 拒绝导致未处理的异常。此外,可以在全局配置 `axios` 的拦截器,统一处理网络错误或响应异常 [^3]。 ```javascript axios.interceptors.response.use( (response) => { return response; }, (error) => { console.error('全局错误拦截:', error); return Promise.reject(error); } ); ``` ### 文件类型识别与 MIME 类型处理 前端在处理下载或展示文件时,应根据后端返回文件类型(如 `.pdf`、`.xlsx`)设置对应的 `Content-Type` 和文件名扩展名,确保浏览器能正确解析和展示文件内容 [^4]。 ### 相关问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值