浏览器响应
Content-Disposition 响应头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地。
//强制浏览器以附件下载
response.setHeader("content-disposition", "attachment;filename=" + fileName);
//浏览器尝试打开
response.setHeader("content-disposition", "inline;filename=" + fileName);
浏览器会根据资源类型去判断是否支持,如果支持时会尝试去在页面上展示该资源。浏览器判断资源类型是根据返回头 Content-Type 的值
直接下载
window.location.href = url
window.open(url)
// 会新开窗口下载,体验不好window.open(url,"_self")
注意:在当前页面使用location.href = url
或open(url,"_self")
时,如果请求的是浏览器支持展示的格式,浏览器地址就会跳转到对应url,并直接展示,否则作为附件下载。所以说浏览器支持展示的文件等于是不能下载的。
iframe下载
function download(){
const ifm = document.createElement("iframe");
ifm.style.display = "none";
ifm.src = downloadFileUrl;
document.body.appendChild(ifm);
}
-
a标签 download
function download(){
const a = document.createElement("a")
a.style.display="none"
a.href=url
a.setAttribute("download",fileName) // 设置a为下载属性,并设置下载文件名
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
}
HTML5新增
- download只适用于同源 URL,不能跨域
-
a标签 blob
请求时指定responseType属性为blob
请求可能需要处理成Blob对象
- 然后使用
URL.createObjectUrl
将 Blob 对象转为 blob:URL 最后再使用 a 标签 download下载
downloadFile (path, name) {
const xhr = new XMLHttpRequest();
xhr.open('get', path);
xhr.responseType = 'blob';
xhr.send();
xhr.onload = function () {
if (this.status === 200 || this.status === 304) {
// 如果是IE10及以上,不支持download属性,采用msSaveOrOpenBlob方法,但是IE10以下也不支持msSaveOrOpenBlob
if ('msSaveOrOpenBlob' in navigator) {
navigator.msSaveOrOpenBlob(this.response, name);
return;
}
// const blob = new Blob([this.response], { type: xhr.getResponseHeader('Content-Type') });
// const url = URL.createObjectURL(blob);
const url = URL.createObjectURL(this.response);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = name;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
};
}
可以构建请求,添加 header 信息,可以跨域
- 可以监听进度
- 缺点:要接收完整个Blob对象再转成URL形式,Blob大小有限制,堆内存可能也会爆炸,不适用于大文件下载场景
Blob对象的Max Size,在Chrome上是2GB,Firefox是800MiB,其他浏览器略有差异