通过 Blob 对二进制流文件下载实现文件保存下载

原理:前端将二进制文件做转换实现下载: 请求后端接口->接收后端返回的二进制流(通过二进制流(Blob)下载,把后端返回的二进制文件放在 Blob 里面)->再通过file-saver插件保存

页面上使用:

<span @click="downloadFile">下载当前文件模板</span>downloadFile() {let dowloadUrlif (this.dowloadUrl) {dowloadUrl = this.dowloadUrl }else if (this.fullPathUrl) {dowloadUrl = this.fullPathUrl}downloadGet(dowloadUrl, `${this.fileName}.csv`, {})
},

在这里插入图片描述

保存文件:

import { saveAs } from 'file-saver'

发起请求通用方法(更改 axios 的 responseType):

// 通用下载方法,blob形式--【post请求】
export function download(url, params, filename, config) {downloadLoadingInstance = Loading.service({text: '正在下载数据,请稍候',spinner: 'el-icon-loading',background: 'rgba(0, 0, 0, 0.7)'})return service.post(url, params, {transformRequest: [(params) => {return tansParams(params)}],headers: { 'Content-Type': 'application/x-www-form-urlencoded' },responseType: 'blob', // 指定响应类型为二进制数据...config}).then(async(data) => {const isLogin = await blobValidate(data)if (isLogin) {const blob = new Blob([data])saveAs(blob, filename)} else {const resText = await data.text()const rspObj = JSON.parse(resText)const errMsg =errorCode[rspObj.code] || rspObj.msg || errorCode['default']Message.error(errMsg)}downloadLoadingInstance.close()}).catch((r) => {console.error(r)Message.error('下载文件出现错误,请联系管理员!')downloadLoadingInstance.close()})
}
// 通用下载方法,blob形式--【get请求】
export function downloadGet(url, filename, config) {downloadLoadingInstance = Loading.service({text: '正在下载数据,请稍候',spinner: 'el-icon-loading',background: 'rgba(0, 0, 0, 0.7)'})return service.get(url, {headers: { 'Content-Type': 'application/x-www-form-urlencoded' },responseType: 'blob',// 指定响应类型为二进制数据...config}).then(async(data) => {const isLogin = await blobValidate(data)if (isLogin) {const blob = new Blob([data])saveAs(blob, filename)} else {const resText = await data.text()const rspObj = JSON.parse(resText)const errMsg =errorCode[rspObj.code] || rspObj.msg || errorCode['default']Message.error(errMsg)}downloadLoadingInstance.close()}).catch((r) => {console.error(r)Message.error('下载文件出现错误,请联系管理员!')downloadLoadingInstance.close()})
}

封装的方法:

/**
* 参数处理
* @param {*} params  参数
*/
export function tansParams(params) {let result = ''for (const propName of Object.keys(params)) {const value = params[propName]var part = encodeURIComponent(propName) + '='// if (value !== null && value !== "" && typeof (value) !== "undefined") {if (value !== null && typeof (value) !== 'undefined') {if (typeof value === 'object') {for (const key of Object.keys(value)) {if (value[key] !== null && value[key] !== '' && typeof (value[key]) !== 'undefined') {const params = propName + '[' + key + ']'var subPart = encodeURIComponent(params) + '='result += subPart + encodeURIComponent(value[key]) + '&'}}} else {result += part + encodeURIComponent(value) + '&'}}}return result
}// 验证是否为blob格式
export async function blobValidate(data) {try {const text = await data.text()JSON.parse(text)return false} catch (error) {return true}
}// errorCode.js: 
export default {'401': '认证失败,无法访问系统资源','403': '当前操作没有权限','404': '访问资源不存在','default': '系统未知错误,请反馈给管理员'
}

点击"下载":

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

相关技术

Blob
概念: Blob 对象表示一个不可变的, 原始数据的类文件对象,它的数据可以按文本或二进制格式进行读取。

Blob 构造函数

const aBlob = new Blob(array, option)

第一个参数是一个类数组, 必填
第二个参数非必填有两个属性: type, 表示MIME类型, 默认值是’'。还有一个是endings 表示 /n 换行符如何被写入,默认值是’transparent’保持不变, 还有’native’按照宿主机的换行符

总结

前端实现文件的下载主要有两种方式,直接打开下载链接和通过 Blob 对二进制流文件下载,实际用那种方法可以看后端的返回值和请求方式

其他:

根据返回值构造 Blob 函数并转换成 URL ,动态创建 a 标签打开 URL参考:
https://huaweicloud.csdn.net/63a55dc4b878a545459452ae.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/107689.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

上海亚商投顾:三大指数小幅下跌 光刻机概念股午后走强

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 三大指数昨日小幅调整&#xff0c;创业板指走势较弱。减肥药概念股继续大涨&#xff0c;常山药业2连板&#x…

MySQL日常使用记录

1.时间 1.1.时间格式化 yyyy-MM-dd HH:mm:ss格式&#xff0c;如下&#xff1a; select date_format(now(), %Y-%m-%d %H:%i:%s) from dual;date_format函数是将date类型按照指定的格式转换成varchar类型 1.2.日期加减 当前天 1 天 select date_format(now(), %Y-%m-%d), …

概念解析 | 揭秘视觉与语言交叉模型:CLIP和BLIP的介绍

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:CLIP和BLIP模型。 揭秘视觉与语言交叉模型:CLIP和BLIP的介绍 🎯 [LB: 0.45836] ~ BLIP+CLIP | CLIP Interrogator | Kaggle 大纲: 背景介绍原理介绍和推导 CLIP模型BLIP模…

外观数列问题

给定一个正整数 n &#xff0c;输出外观数列的第 n 项。 「外观数列」是一个整数序列&#xff0c;从数字 1 开始&#xff0c;序列中的每一项都是对前一项的描述。 你可以将其视作是由递归公式定义的数字字符串序列&#xff1a; countAndSay(1) "1" countAndSay(n…

继续上一个爬虫,所以说selenium加browsermobproxy

继续&#xff0c;书接上回&#xff0c;这次我通过jsrpc&#xff0c;也学会了不少逆向的知识&#xff0c;感觉对于一般的网站应该都能应付了。当然我说的是简单的网站&#xff0c;遇到那些混淆的&#xff0c;还有那种猿人学里面的题目&#xff0c;还是免谈了。那种需要的水平太高…

python-爬虫-urllib3

导入模块 import urllib3urllib3&#xff1a;功能强大、条理清晰、用于HTTP客户端的python网络请求库 重要特征 1.线程安全 2.连接池 3.客户端SSL/TLS验证 4.使用分段编码长传文件 5.重试请求和处理HTTP复位的助手 6.支持gzip和deflate编码 7.HTTP和SOCKS的代理支持 8.100%的…

【Linux网络】TCP/IP三次握手、四次挥手流程

目录 一、三次握手&#xff0c;建立连接 二、四次挥手&#xff0c;断开连接 三、主要字段 1、标志位&#xff08;Flags&#xff09; 2、序号&#xff08;sequence number&#xff09; 3、确认号&#xff08;acknowledgement number&#xff09; 四、三次握手的报文变化 五…

linux 查看进程的几个方法

linux 查看进程的几个方法 一、ps aux a&#xff1a;显示当前终端下的所有进程信息&#xff0c;包括其他用户的进程。 u&#xff1a;使用以用户为主的格式输出进程信息。 x&#xff1a;显示当前用户在所有终端下的进程。 ps命令用于报告当前系统的进程状态。可以搭配kill指…

【网络编程】深入理解TCP协议一(三次握手四次挥手、标记位、确认应答机制、超时重传机制)

TCP协议 1.三次握手四次挥手2.TCP协议段格式3.标记位介绍4.确认应答机制5.超时重传机制 1.三次握手四次挥手 当客户端发起连接请求时&#xff0c;SYN需要被设置位1&#xff0c;告诉服务器客户端希望建立一个链接服务器收到响应之后会回复 SYNACK&#xff0c;表示确认了客户端地…

基于SSM的海鲜自助餐厅系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

如何实现一个数据库的 UDF?图数据库 NebulaGraph UDF 功能背后的设计与思考

大家好&#xff0c;我是来自 BOSS直聘的赵俊南&#xff0c;主要负责安全方面的图存储相关工作。作为一个从 v1.x 用到 v3.x 版本的忠实用户&#xff0c;在见证 NebulaGraph 发展的同时&#xff0c;也和它一起成长。 BOSS直聘和 NebulaGraph 关于 NebulaGraph 在 BOSS直聘的应…

手搓消息队列【RabbitMQ版】

什么是消息队列&#xff1f; 阻塞队列&#xff08;Blocking Queue&#xff09;-> 生产者消费者模型 &#xff08;是在一个进程内&#xff09;所谓的消息队列&#xff0c;就是把阻塞队列这样的数据结构&#xff0c;单独提取成了一个程序&#xff0c;进行独立部署~ --------&…