HTML download 属性
在同源下载是没有问题的
<a href="http://localhost:8000/test.png" download="test.png"> //本地同源
工作中附件可能是多个不同域名下返回的
<a href="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-assets/v3/static/img/logo.a7995ad.svg~tplv-t2oaga2asx-image.image" download="a7995ad.svg">
//本地下载掘金logo
这种下载方法 项目中会用到多次,所以我们来封装一个公共方法。
获取文件名
function getFileName(url) {
const name = url.split('/');
return name.pop();
}
获取到文件内容 创建 blob对象,并转换为 blob string
fetch(url).then(response=>{
return response.blob();
})
.then(blob=>{
//转换为 blob string
const blobUrl = window.URL.createObjectURL(blob); //blob:http://localhost:8000/59f8792c-c863-4bcc-b891-6fedb25e29bd
//然后我们创建a标签
const blobUrl = window.URL.createObjectURL(blob);
const tempLink = document.createElement('a');
tempLink.style.display = 'none';
tempLink.href = blobUrl;
document.body.appendChild(tempLink);
//触发点击事件
tempLink.click();
//触发下载之后清掉
setTimeout( ()=> {
URL.revokeObjectURL(blobUrl);
document.body.removeChild(tempLink);
});
}
我们在整合一下通用的方法
/**
*
* @param url 附件地址
* @param download 附件可以预览或者下载
*/
function fileDownload(url, download = true) {
function getFileName(url) {
const name = url.split('/'); return name.pop(); }
const filename = getFileName(url);
fetch(url)
.then(response=>{
return response.blob();
})
.then(blob=>{
const blobUrl = window.URL.createObjectURL(blob);
const tempLink = document.createElement('a');
tempLink.style.display = 'none';
tempLink.href = blobUrl;
if (download) {
//下载
tempLink.setAttribute('download', filename);
}else{
//预览
tempLink.setAttribute('target', '_blank');
}
document.body.appendChild(tempLink);
tempLink.click();
setTimeout( ()=> {
URL.revokeObjectURL(blobUrl);
document.body.removeChild(tempLink);
})}
}
我们的通用下载就写好了。
方法的核心就在获取附件之后用 createObjectURL
把附件转为blob.强制附件url使其同源。
总结
- fetch 可使用 axios 或者 原生XMLHttpRequest 等其他方式代替,只要能正确获取到blob对象。
import axios from 'axios';
axios.get(url, { responseType: 'blob'})
.then(response=>{
// ...code
})
const xMLHttpRequest = new XMLHttpRequest();
xMLHttpRequest.open("GET", url, true);
xMLHttpRequest.responseType = 'blob';
xMLHttpRequest.onload = function () {
// ...code
}
xMLHttpRequest.send();
- 获取文件名也可以自己喜欢的方式和库去实现
import {split, last, nth, partialRight, flow} from 'lodash';
const getFileName = flow([partialRight(split, '/'), last]);
const filename = getFileName(url);