前端Ajax文件流下载及响应头文件名fileName获取
使用ajax下载文件令人头痛欲裂的是fileName文件名的获取,网上寻找各种格式化响应头的方法,奈何五花八门,无一凑效,机缘巧合之下发现axios内部对响应头有做处理,于是火速翻开axios源码浏览借鉴(实则cv)使用a标签下载文件,添加download属性可以自动获取文件名,但需求需要没有文件或者发生错误是给出弹窗提示,a标签下载显然无法实现功能!...
·
前端Ajax文件流下载及响应头文件名fileName获取
1.使用传统a标签下载
使用a标签下载文件,添加download属性可以自动获取文件名,但需求需要没有文件或者发生错误是给出弹窗提示,a标签下载显然无法实现功能!
<a href="完整下载地址" download>下载文件</a>
2.使用Ajax下载文件流
// 下载文件方法
function downloadFile() {
var url = "请求地址 + 请求参数拼接"
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true); // 也可以使用POST方式,根据接口
xhr.responseType = "blob"; // 返回类型blob
// 定义请求完成的处理函数,请求前也可以增加加载框/禁用下载按钮逻辑
xhr.onload = function (res) {
// 判断获取响应头方法是否存在,存在则返回格式化后的响应头,通过自定义parseHeaders()方法
var responseHeaders = 'getAllResponseHeaders' in xhr ? parseHeaders(xhr.getAllResponseHeaders()) : null;
// 响应头content-disposition存放的文件名字符串数据,
// 格式如(Content-Disposition: attachment;filename=2022011340798353+%287%29+%281%29.pdf)返回格式不一致怼后端
var disposition = responseHeaders["content-disposition"];
// 请求完成
if (this.status === 200) {
// 捕获异常,给出错误提示,disposition文件名信息不存在,代表文件流未返回
if (!disposition) {
var reader = new FileReader();
reader.readAsText(xhr.response, "utf-8");
reader.onload = function () {
var data = JSON.parse(reader.result);
alert(data.message||"文件不存在!");
}
return;
}
// 从响应头content-disposition字符串(类似这种格式attachment;filename=2022011340798353+%287%29+%281%29.pdf)取出文件名
var fileName = disposition.split(";")[1].split("filename=")[1]
// 此处兼容ie
if (window.navigator.msSaveOrOpenBlob) {
try {
navigator.msSaveOrOpenBlob(xhr.response, fileName);
} catch (e) {
console.log(e);
}
} else {
// 正常动态创建a标签下载(常规操作)
var link = document.createElement("a");
var body = document.querySelector("body");
link.href = window.URL.createObjectURL(xhr.response);
link.download = fileName;
// fix Firefox
link.style.display = "none";
body.appendChild(link);
link.click();
body.removeChild(link);
window.URL.revokeObjectURL(link.href);
}
} else{
alert("网络错误!");
}
};
// 发送ajax请求
xhr.send()
}
3.格式化响应头parseHeaders方法(本文重点)
使用ajax下载文件令人头痛欲裂的是fileName文件名的获取,网上寻找各种格式化响应头的方法,奈何五花八门,无一凑效,机缘巧合之下发现axios内部对响应头有做处理,于是火速翻开axios源码浏览借鉴(实则cv)
// 响应头格式化,获取文件名
function parseHeaders(headers) {
var parsed = {};
var key;
var val;
var i;
if (!headers) { return parsed; }
myForEach(headers.split('\n'), function parser(line) {
i = line.indexOf(':');
key = trim(line.substr(0, i)).toLowerCase();
val = trim(line.substr(i + 1));
if (key) {
if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) {
return;
}
if (key === 'set-cookie') {
parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]);
} else {
parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
}
}
});
return parsed;
};
function myForEach(obj, fn) {
if (obj === null || typeof obj === 'undefined') {
return;
}
if (typeof obj !== 'object') {
/*eslint no-param-reassign:0*/
obj = [obj];
}
if (Array.isArray(obj)) {
for (var i = 0, l = obj.length; i < l; i++) {
fn.call(null, obj[i], i, obj);
}
} else {
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
fn.call(null, obj[key], key, obj);
}
}
}
}
function trim(str) {
return str.replace(/^\s*/, '').replace(/\s*$/, '');
}
更多推荐
已为社区贡献1条内容
所有评论(0)