最近项目中遇到了不同的点击下载的场景,后台表格点击下载excel文件以及点击下载zip压缩包文件
分别对几种场景的点击下载进行一个总结:
a标签
查看mdn对于a标签下载的描述:
let url = "xxxx.zip"
`<a href={url} download>点我下载</a>`
blob文本文件下载
const exportHandle = () => {
setExportLoading(true);
const request = extend({
timeout: 50000,
// 处理http请求错误 未处理业务错误 业务错误baseRequest中处理
errorHandler: httpErrorHandler,
credentials: 'include', // 默认请求是否带上cookie
});
request('you_url', {
method: 'get',
responseType: 'blob',
getResponse: true,
})
.then(({ data, response }) => {
// 实例读取文件对象
const r = new FileReader();
r.onload = function () {
try {
// this.result为FileReader获取blob数据,如果返回报错信息,则是正确的json数据,JSON.parse会正常转换
// 如果返回文件流,则JSON.parse时会报错,走catch代码块(进行正常的文件下载)
const resData = JSON.parse(this.result as string);
// resData是后端返回的json数据
if (resData.code === -1) {
message.error(resData.msg || '导出错误');
return;
}
} catch (error) {
downLoad(data, response);
}
};
r.readAsText(data);
})
.catch((error) => {
console.log(error);
message.error('导出错误');
})
.finally(() => {
setTimeout(() => {
setExportLoading(false);
}, 1000);
});
};
json无法解析,说明返回的是blob文件,此时,catch到download中执行逻辑
// 下载
const downLoad = (data: BlobPart, response: Response) => {
let blob = new Blob([data], { type: 'application/zip' });
// 获取 获取响应头 heads 中的 filename 文件名
const filename = response.headers.get('content-disposition');
let changeFileName = '';
if (filename) {
// 解析文件名
changeFileName = decodeURI(filename.split('=')[1]);
changeFileName = decodeURIComponent(changeFileName.substring(filename.indexOf(' ')));
}
let fileName = changeFileName || '数据.zip';
// 创建一个 a 标签
const link = document.createElement('a');
// 不显示a标签
link.style.display = 'none';
// 给a 标签的href属性赋值
link.href = URL.createObjectURL(blob);
link.setAttribute('download', fileName);
// 把a标签插入页面中
document.body.appendChild(link);
link.click();
// 点击之后移除a标签
document.body.removeChild(link);
};
URL.createObjectURL() 是 JavaScript 中的一个方法,属于 URL 构造函数的一部分。这个方法的作用是创建一个临时的、唯一的、以 blob: 协议开头的URL,这个URL可以用来表示一个 Blob 对象或 File 对象。
当你调用 URL.createObjectURL() 并传入一个 Blob 或 File 对象时,它会返回一个表示该对象的URL。这个URL可以用于任何需要URL的地方,比如在 <img> 标签的 src 属性中设置图片源,在 <a> 标签的 href 属性中设置下载链接,或者在 <script> 标签的 src 属性中加载一个JavaScript文件。
图片下载
// 加载的图片对象
function(img, filename){
let a = document.createElement("a");
let canvas = document.createElement('canvas');
let context = canvas.getContext('2d');
let width = domImg.naturalWidth;
let height = domImg.naturalHeight;
context.drawImage(img, 0, 0);
a.href = canvas.toDataURL('image/jpeg');
//a.href = canvas.toDataURL('image/png'); ...
a.download = filename;
a.style.display = "none";
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
}
function downloadImage(blob, filename) {
// 创建Blob对象
const imageBlob = new Blob([blob], { type: 'image/png' });
// 创建临时URL
const imageUrl = URL.createObjectURL(imageBlob);
// 创建下载链接
const link = document.createElement('a');
link.href = imageUrl;
link.download = filename || 'download.png';
link.style.display = 'none'; // 避免显示在页面上
document.body.appendChild(link);
// 触发下载
link.click();
// 清理
document.body.removeChild(link);
URL.revokeObjectURL(imageUrl);
}
// 假设你有一个包含图片数据的ArrayBuffer
const imageArrayBuffer = ...;
// 调用函数下载图片
downloadImage(imageArrayBuffer);