vue 前端通过后端返回的文件流,直接在浏览器下载文件(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) => { });
    },

### Vue 中处理后端返回文件流以实现文件下载的方法 在 Vue 应用中,当后端返回的是文件流时,可以通过前端代码将其转换为可下载文件。以下是具体实现方式: #### 方法一:通过 `Blob` 和动态创建 `<a>` 标签实现下载 此方法适用于大多数场景,能够灵活设置文件名和 MIME 类型。 ```javascript exportBill(data).then(res => { const blob = new Blob([res.data], { type: 'application/vnd.ms-excel' }); // 设置文件类型[^2] const url = window.URL.createObjectURL(blob); const link = document.createElement('a'); link.style.display = 'none'; link.href = url; link.setAttribute('download', 'xxx.xls'); // 自定义文件名称 document.body.appendChild(link); link.click(); document.body.removeChild(link); // 移除临时 DOM 元素 window.URL.revokeObjectURL(url); // 释放 URL 对象资源 }).catch(err => { console.error("下载失败", err); }); ``` 上述代码片段展示了如何将后端返回的二进制数据(即文件流)转化为浏览器中的文件对象,并触发下载行为。 --- #### 方法二:封装通用工具函数供项目调用 为了提高代码复用性和维护性,可以将文件下载逻辑封装成一个独立的工具函数,在多个地方重复使用。 ```javascript function downloadFile(response, fileName) { const content = response.data; const blob = new Blob([content], { type: 'application/octet-stream' }); if (window.navigator && window.navigator.msSaveOrOpenBlob) { window.navigator.msSaveOrOpenBlob(blob, fileName); // IE兼容模式[^3] } else { const elink = document.createElement('a'); elink.download = fileName || '未命名'; // 默认文件名为“未命名” elink.style.display = 'none'; elink.href = URL.createObjectURL(blob); document.body.appendChild(elink); elink.click(); URL.revokeObjectURL(elink.href); // 清理内存泄漏风险 document.body.removeChild(elink); } } ``` 该工具函数支持跨浏览器运行,包括对旧版 Internet Explorer 的特殊适配。 --- #### 方法三:全局注册 `$download` 工具方法以便组件间共享功能 如果希望在整个应用范围内都能方便地调用文件下载功能,则可以在入口文件(如 `main.js`)中进行如下配置: ```javascript import Vue from 'vue'; // 定义下载辅助函数 const downloadHelper = function(response, filename) { const blob = new Blob([response.data]); const aLink = document.createElement('a'); const href = window.URL.createObjectURL(blob); aLink.href = href; aLink.download = filename || 'default_name.txt'; // 提供默认文件名作为兜底方案 document.body.appendChild(aLink); aLink.click(); document.body.removeChild(aLink); window.URL.revokeObjectURL(href); }; Vue.prototype.$download = downloadHelper; // 此处省略其他初始化代码... new Vue({ render: h => h(App), }).$mount('#app'); ``` 这样做的好处在于任何 Vue 组件都可以直接通过 `this.$download()` 调用统一的文件下载服务[^1]。 --- ### 注意事项 - **MIME 类型匹配**:确保指定正确的 MIME 类型来描述目标文件的内容性质,比如 Excel 表格应设为 `'application/vnd.ms-excel'` 或者更广泛的 `'application/octet-stream'` 来表示未知二进制数据。 - **错误捕获机制**:考虑到网络异常或者服务器响应不符合预期的情况,建议加入全面的日志记录以及友好的用户体验提示。 - **性能优化考量**:对于特别大体积的文件传输过程可能引发内存占用过高问题,需评估实际需求决定是否采用分片加载等方式缓解压力。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值