项目中,我们有时候会遇到下载文件(如jpg, excel,doc,pdf等等)的功能,在此总结方式及其使用场景。
1.比较常见的是通过a标签的href属性直接访问文件url地址。
<a href="文件url">xxx</a>
这种方式excel, doc等文件会直接下载,遇到jpg,pdf这种浏览器会直接预览不会下载 。看网上有说,加上给a标签加上download属性值图片、pdf也能实现下载,但我试了下还是会直接预览(Chrome 76.0.3809.100)。最后看到其他人的代码实现,发现通过在url上加上attname参数图片、pdf也能实现下载
<a href="文件url?attname=filename.jpg">xxx</a>
attname参数值需要带扩展名,要不然识别不了文件类型。
这种方式下载一些不用验证的资源是可以,但如果下载接口需要验证,需要你在请求头带token,这种方式就行不通了。
2.第二中通过发送ajax请求,实现下载,这里使用的是axios。
a 标签download属性值需要带文件类型后缀
//下载文件的操作我们可能会多次调用,可以写入项目公用方法中
//util.js
import axios from 'axios'
//获取blob
downloadFile(url, params, withToken = true){
const token = this.getCookie('X-Access-Token')
//是否需要携带token
const headers = withToken
? { 'X-Access-Token': token }
: {}
return axios({
url,
method: 'GET',
params,
responseType: 'blob',
headers,
})
}
//实现下载
downloadBlobFile(blob, filename) {
const objUrl = window.URL.createObjectURL(blob)
const a = document.createElement('a')
if ('download' in a) {
document.body.appendChild(a)
a.style.display = 'none'
a.href = objUrl
a.download = filename
a.click()
window.URL.revokeObjectURL(objUrl)
document.body.removeChild(a)
return
}
// IE
navigator.msSaveBlob(blob, filename)
}
//页面使用
async downloadClick() {
const res = await utils.downloadFile(url, params)
utils.downloadBlobFile(res.data, `${fileName}.xlsx`)
}
//法二
fetch(url).then(res => res.blob().then(blob => {
let a = document.createElement('a');
let url = window.URL.createObjectURL(blob);
a.href = url;
a.download = filename;
a.click();
window.URL.revokeObjectURL(url);
}))
3.批量下载文件到一个压缩包中。使用场景:如批量下载图片、文件到一个压缩包中
用到的第三方库:jszip、file-saver、axios
//引入jszip、file-saver、axios
import JSZip from 'jszip';
import axios from 'axios';
import { saveAs } from 'file-saver';
//实现思路是先把所有文件通过axios以arraybuffer为响应类型获取到数据,
//再通过jszip依次添加并生成zip文件
//最后通过file-saver下载到本地
createAxiosQueue(urlList) {
const promiseQueue = []
urlList.forEach(url => {
promiseQueue.push(axios({
method: 'GET',
url,
// responseType: 'blob',
responseType: 'arraybuffer',
}))
})
return promiseQueue
}
const axiosQueue = this.createAxiosQueue(this.codeUrlList)
axios.all(axiosQueue)
.then((res) => {
const zip = new JSZip()
res.forEach((item, index) => {
//图片文件
zip.file(`对应每张图片的名称.png`, item.data, {binary: true})
})
zip.generateAsync({ type: 'blob' })
.then(content => {
saveAs(content, `xxx.zip`);
}).catch(() => {
})
})
4.有时候我们需要把页面中显示的图片下载到本地, 一种方式是通过html2canvas file-saver再下载,再此不赘述;还有一种也可以获取img标签的url 通过动态创建a标签下载(如1)
funDownload(url, filename) {
// 创建隐藏的可下载链接
let eleLink = document.createElement('a');
eleLink.download = filename;
eleLink.style.display = 'none';
eleLink.href = url
// 触发点击
document.body.appendChild(eleLink);
eleLink.click();
// 然后移除
document.body.removeChild(eleLink);
}