js:使用a标签下载图片及pdf文件等资源
一个PC端的项目(vue),开发是在google浏览器测试的,刚开始是使用的以下代码实现文件下载,图片,pdf,doc等:openDownload(link, name) {const x = new XMLHttpRequest();x.open('GET', link, true);x.responseType = 'blob';x.onload = function () {const ur
·
一个PC端的项目(vue),开发是在google浏览器测试的,刚开始是使用的以下代码实现文件下载,图片,pdf,doc等:
openDownload(link, name) {
const x = new XMLHttpRequest();
x.open('GET', link, true);
x.responseType = 'blob';
x.onload = function () {
const url = window.URL.createObjectURL(x.response);
const a = document.createElement('a');
a.href = url;
a.download = name || '';
a.click();
};
x.send();
},
在google浏览器中,这个方法已经可以完成上诉的各类文件的下载。当我使用360家的两款浏览器测试的时候,发下下载图片会报跨域,然后想起之前H5端使用canvas处理跨域下载的方法,此处用上,更改后的代码如下:
async openDownload(urls, name) {
const link = urls;
const files = link.split('.');
const type = files[files.length - 1];
const x = new XMLHttpRequest();
if (['jpg', 'png', 'jpeg', 'gif'].includes(type)) { // 图片
const image = await this.getBase64Image(link);
x.open('GET', image, true);
} else { // 非图片
x.open('GET', link, true);
}
x.responseType = 'blob';
x.onload = function () {
const url = window.URL.createObjectURL(x.response);
const a = document.createElement('a');
a.href = url;
a.download = name || '';
a.click();
};
x.send();
},
// 图片转base64
getBase64Image(img) {
return new Promise((resolve, reject) => {
if (!img) {
reject(new Error(null));
}
const canvas = document.createElement('canvas');
const image = new Image();
image.setAttribute('crossOrigin', 'anonymous');
image.src = `${img}?v=${Math.random()}`;
image.onload = () => {
canvas.width = image.width;
canvas.height = image.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(image, 0, 0, image.width, image.height);
const ext = image.src.substring(image.src.lastIndexOf('.') + 1).toLowerCase();
resolve(canvas.toDataURL(`image/${ext}`));
};
image.error = () => {
reject(new Error(null));
};
});
},
以上代码可以在google中实现完美下载,但是测试其他浏览器的时候,特别是ie和360的兼容模式,发现gg了。
和同事商量讨论的半天,终于得出以下解决方案:
openDownload(urls, name) {
const link = urls;
const lastIndex = link.split('.').length - 1;
const type = link.split('.')[lastIndex];
if (['jpg', 'png', 'jpeg', 'gif'].includes(type)) { // 图片
this.getBase64Image2(link, (image) => {
this.XMLHttpRequest(image, `${name}.${type}`, 'image');
});
} else { // 非图片
this.XMLHttpRequest(link, name, 'file');
}
},
XMLHttpRequest(link, name, type) {
console.log(name);
const x = new XMLHttpRequest();
x.open('GET', link, true);
x.responseType = 'blob';
x.onload = function () {
console.log('onload');
const blob = x.response;
const url = window.URL.createObjectURL(blob);
// 判断是否是IE浏览器
if (window.navigator.msSaveBlob) {
try {
window.navigator.msSaveBlob(type === 'image' ? link : blob, name);
} catch (e) {
console.log(e);
}
} else {
const a = document.createElement('a');
a.href = url;
a.download = name || '';
a.click();
}
};
x.send();
},
getBase64Image2(img, cb) {
const canvas = document.createElement('canvas');
const image = new Image();
image.setAttribute('crossOrigin', 'anonymous');
image.src = `${img}?v=${Math.random()}`;
image.onload = () => {
canvas.width = image.width;
canvas.height = image.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(image, 0, 0, image.width, image.height);
const ext = image.src.substring(image.src.lastIndexOf('.') + 1).toLowerCase();
const base64 = canvas.toDataURL(`image/${ext}`);
if (window.navigator.msSaveBlob) { // IE
this.dataURLtoBlob(base64, (blob) => {
cb(blob);
});
} else { // 非IE
cb(base64);
}
};
},
dataURLtoBlob(base64, cb) {
const arr = base64.split(',');
const bstr = atob(arr[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n > 0) {
n -= 1;
u8arr[n] = bstr.charCodeAt(n);
}
const blob = new Blob([u8arr]);
cb(blob);
},
测试结果(UC急速有知道为啥的吗?)
更多推荐
已为社区贡献22条内容
所有评论(0)