作为一名前端开发者,我们经常遇到下载文件的场景(包括:图片,文档,压缩包等),解决办法五花八门,而且使用场景过于单一...
常规方法
常规方法我们会用a标签
或者form表单
来实现下载功能。
a 标签
a标签的用法都很熟悉,但是却有两个致命缺点:
不能携带鉴权信息
token
兼容性问题
只有 火狐和谷歌浏览器支持!!!
form 表单
form 表单
用法很早就有,但是有个明显的缺点:不能修改文件名称
那么需要一个能携带
token
信息且能修改文件名称
还要兼容各大浏览器
怎么结局这个问题呢?本文将为你带来一种 能携带token
信息且能修改文件名称
还要兼容各大浏览器
的方法!
一生二 二生三 三生万物
核心利于XMLHttpRequest
和 a标签
来解决携带 token
信息,利用微软自带的msSaveBlob
方法来兼容IE浏览器
首先能携带token
信息
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
//设置请求头参数的方式,如果没有可忽略此行代码
xhr.setRequestHeader("Authorization",`Bearer ${idToken}`));
//设置响应类型为 blob xhr.open必须为 异步
xhr.responseType = 'blob';
//关键部分
xhr.onload = function (e) {
//如果请求执行成功
if (this.status == 200) {
let blob = this.response;
let a = document.createElement('a');
// blob.type = "application/octet-stream";
let url = window.URL.createObjectURL(blob);
a.href = url;
a.download = decodeURIComponent(xhr.getResponseHeader("content-disposition").split(";")[1].split("filename=")[1]);
document.body.appendChild(a); // 火狐浏览器 必须把元素插入body中
a.click();
document.body.removeChild(a);
//释放之前创建的URL对象
window.URL.revokeObjectURL(url);
}
}
然后解决兼容IE浏览器
问题并完善异常捕获
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
// xhr.open('POST', url, true); // post 请求
// xhr.setRequestHeader("content-type", 'application/json'); // post请求携带body体参数,需要设置此行
//设置请求头参数的方式,如果没有可忽略此行代码
xhr.setRequestHeader("Authorization",`Bearer ${idToken}`));
//设置响应类型为 blob
xhr.responseType = 'blob';
// 关键部分
xhr.onload = function (e) {
// 如果请求执行成功
if (this.status == 200) {
let blob = this.response
let a = document.createElement('a')
// blob.type = "application/octet-stream";
let url = window.URL.createObjectURL(blob)
let fileName = decodeURIComponent(escape(xhr.getResponseHeader('content-disposition').split(';')[1].split('filename=')[1]))
if (window.navigator.msSaveBlob) {
try {
window.navigator.msSaveBlob(blob, fileName)
} catch (e) {
console.log(e)
}
} else {
a.href = url
a.download = fileName
document.body.appendChild(a) // 火狐浏览器 必须把元素插入body中
a.click()
document.body.removeChild(a)
// 释放之前创建的URL对象
window.URL.revokeObjectURL(url)
}
} else { // 失败后需要将blob对象转换为 json 来获取异常信息
const reader = new FileReader();
reader.readAsText(this.response, 'utf-8');
reader.onload = () => {
const { header } = JSON.parse(reader.result);
console.error(header.msg)
}
}
}
xhr.send()
// xhr.send(JSON.stringify({ id, orgNo, keyWord })) // 将携带参数转化为 JSON