前言
在实际开发中我们经常会遇见下载文件的场景,比如下载合同,下载文件
下载文件有2种方式,一种是后端返回二进制流,前端通过blob对象接受根据不同类型下载
还有一种把地址直接在浏览器新窗口打开浏览器打开pdf可以预览和下载,其他文件直接下载
但不管是那种方式,原理都是一样的只是取决于谁来执行转化代码
代码实现
1.封装api-根据直接后端接口而定(注意要在请求时标明是二进制文件流)
// 文件-图片下载export function downloadfile (data) { return request({ url: '/download/file', method: 'post', data, // 指定请求类型为二进制流 // 不写可能会造成下载成功的图片和文件是看不到和没有内容的 responseType: 'blob' })}
2.下载不同文件和图片在项目中可能经常使用-可以封装成一个方法。
2.1在utils下创建download.js文件
export default { // 下载 Excel 方法 excel (data, fileName) { this.download(data, fileName, 'application/vnd.ms-excel') }, // 下载 Word 方法 word (data, fileName) { this.download(data, fileName, 'application/msword') }, // 下载 Zip 方法 zip (data, fileName) { this.download(data, fileName, 'application/zip') }, // 下载 Html 方法 html (data, fileName) { this.download(data, fileName, 'text/html') }, // 下载 Markdown 方法 markdown (data, fileName) { this.download(data, fileName, 'text/markdown') }, // 下载 pdf 方法 pdf (data, fileName) { console.log('data', data) console.log('fileName', fileName) this.download(data, fileName, 'application/pdf') }, // 下载 图片方法 png (data, fileName) { this.download(data, fileName, 'application/png') }, // 兼容写法 stream (data, fileName) { this.download(data, fileName, 'application/octet-stream') }, download (data, fileName, mineType) { // 创建 blob对象 let blob = new Blob([data], { type: mineType }) // 浏览器api 有的不支持-二种都写 window.URL = window.URL || window.webkitURL // 获取链接地址-(内容赋值到临时链接) let href = URL.createObjectURL(blob) // 创建a标签 let downA = document.createElement('a') // 把链接赋值给a标签 downA.href = href // 赋值文件名称 downA.download = fileName // 点击下载 downA.click() // 销毁超连接 window.URL.revokeObjectURL(href) } }
3.在页面中使用
// html<el-button type="info" @click="addclose">下载</el-button>// datadatafile: { url: '文件或者图片地址' } // 引入方法import download from '@/utils/download'// 方法// 下载 async addclose () { const res = await downloadfile(this.datafile) // 下载图片 // 针对性的类型-名称带不带.png都不会受影响 // download.png (res,'测试图片') // 带后缀 // download.png (res,'测试图片.png') // 下载pdf文件 // 针对性的类型-名称带不带.pdf都不会受影响 // download.pdf (res,'pdf文件') // 带后缀 download.pdf (res,'pdf文件.pdf') // 公共方法 // application/octet-stream 相当于公共类型-需要在名称带上指定的后缀-不然下载下来的文件没有后缀名打不开 // download.stream (res,'公共方法.png') // download.stream (res,'公共方法.pdf') }
注意
首先排查下载下来的文件格式是否正确,不正确检查blob对象类型(名称也有关系是否带后缀名)
如果发现下载下来的文件格式后缀正确,内容,图片为空,看不见,排查后端是否把内容转成流,前端在封装api时是否设置responseType: 'blob'
总结:
经过这一趟流程下来相信你也对 vue 后端返回二进制流-前端通过blob对象下载文件-图片 有了初步的深刻印象,但在实际开发中我 们遇到的情况肯定是不一样的,所以我们要理解它的原理,万变不离其宗。加油,打工人!
什么不足的地方请大家指出谢谢 -- 風过无痕