开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情
最近碰到一个问题,需求是点击链接直接就会下载文件,而不是跳到新页面预览文件,但是实现过程中发现了一些问题,就在此记录下来,希望能帮到同样被这个问题困扰的掘友们!
基本函数实现
async downFile(val, key) {
const params = {
key,
prodId: val.prod.id
}
//hide方法是为了增加用户体验的
let hide = this.message.loading("文件下载中", 0)
const res = await getDownLoadUrl(params)
const { code, result, message } = res
if(code === 200 && result.url) {
const ele = document.createElement('a')
ele.setAttribute('href', result.url)
ele.setAttribute('download', result.appendix_name)
ele.setAttribute('target', '_blank')
ele.click()
setTimeout(()=>{
hide()
this.$message.success(`${result.appendix_name}下载成功!`, 1000)
})
} else {
let mess = message
if(!message) {
mess = '下载失败!'
}
hide()
this.$message.error(mess)
}
}
这里首先要对已经忘记了原生JavaScript的掘友们,回顾一下我们刚学JavaScript的时候用的一些属性方法了:
- document对象:我们如果想要操作页面上的某部分,肯定需要先获取到该部分对应的元素,才能进行后续操作对吧。
- createElement:当页面中没有想要的元素,就需要自己创造一个了,createElement()方法可以创建元素节点,返回一个 Element 对象。
- setAttribute:既然元素有了,那么就需要给它设置属性了,setAttribute()方法可以给某个元素设置属性,并为其赋值,不论该元素是原有的还是createElement创造的。
- click:点击事件,上述代码中是直接调用ele对象的点击事件,即点击a标签。
问题在于,这种方法对img、PDF等格式的文件无效,当文件是这些格式时,浏览器默认会打开新页面预览而不会下载。
axios+blob的方法
经过多次尝试,发现了用axios发请求,并结合blob的方法,可以解决这个问题。
axios是一个发送请求和操作请求的轻量级库,大家都知道,就不用多加赘述了。关于blob,它是二进制类型大对象,表示用来存储二进制数据,在我们前端通常用于文件上传,图片预览等等。在 JavaScript 中 Blob 对象表示一个不可变、原始数据的类文件对象,它不一定非得是大量数据,也可以表示一个小型文件的内容。
我们使用构造函数new Blob方法来创建一个blob对象,使用 URL.createObjectURL方法来创建 Blob URL,该方法接收一个 blob 对象,并为其创建一个唯一的 URL。代码如下:
downFile() {
const config = {}
// 这一步可能很关键,特别是在能下载,但是下载下来打开异常的时候。
config.responseType = 'blob'
axios
.get(
'https://img1.baidu.com/it/u=375194120,1211299301&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500',
config
)
.then((res) => {
const blob = new Blob([res.data]) // 将字节流(字符流)转换为 blob 对象
let url = window.URL.createObjectURL(blob)
// 解决 ie 不支持下载 blob资源
if ('msSaveOrOpenBlob' in navigator) {
window.navigator.msSaveOrOpenBlob(blob, 'ceshi.jpg')
return
}
let ele = document.createElement('a')
ele.style.display = 'none'
ele.href = url
ele.download = 'ceshi.jpg'
document.body.appendChild(ele)
ele.click()
document.body.removeChild(ele) // 下载完成移除元素
window.URL.revokeObjectURL(url) // 释放掉blob对象
})
},
end
以上就是我的一点小小的分享,希望能对你有所帮助,感谢!