接到一个需求,其中有一个功能是实现下载图片和文件,我一看,这应该简单吧,用a标签的download属性或者window.open()就可以,没想到后端传回来的不是Blob,而是普通的url,不管是window.open(),还是a的download属性,对于可以打开的链接,他们是不会去下载的。。那就试试将普通的url转化成base64或者Blob这种他们不认识的形式?还好网上有相关代码,改造了一下,代码如下
图片转base64
function image2base64(img) {
const canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, img.width, img.height);
const mime = img.src.substring(img.src.lastIndexOf(".")+1).toLowerCase();
const dataUrl = canvas.toDataURL("image/" + mime);
return dataUrl;
}
// 如果是blob数据,可以直接用这个函数
function download (blob, filename) {
const a = document.createElement('a');
const URL = window.URL || window.webkitURL;
const herf = URL.createObjectURL(blob);
a.href = herf;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(herf);
};
<script>
function downSource(list) {
//如果是文件类型的可以直接下载
if(){
const a = document.createElement('a');
a.href = list.url;
a.download = list.name;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
} else {
// 如果是图片类型的需要转化成blob的形式
const image = new Image();
image.setAttribute("crossOrigin",'use-credentials');
image.src = '../files/test-download.png' + '?' + new Date().getTime();
image.onload = function() {
const imageDataUrl = image2base64(image);
const imageBlobData = dataUrl2Blob(imageDataUrl);
download(imageBlobData, list.name);
}
}
}
</script>
本以为可以大功告成了,没想到下载文件的时候filename没起作用~查了一下,segmentfault.com/q/101000002…
可能需要后端设置一下。嗯~有点麻烦啊,向其他小姐姐求助,她只说了几个字,用xhr和blob,我一试还真行,代码也精简了很多
const request = (list) => {
const req = new XMLHttpRequest();
req.open('GET', list.url, true);
req.responseType = 'blob';
req.setRequestHeader('Content-Type', 'application/json');
req.onload = () => {
const data = req.response;
const blob = new Blob([data]);
if (window.navigator && window.navigator.msSaveOrOpenBlob) { //这是为了兼容ie浏览器,否则点击没有效果
window.navigator.msSaveBlob(blob, list.name);
} else {
const blobUrl = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.download = list.name;
a.href = blobUrl;
a.click();
}
};
req.send(null);
};
ok,结束~