同源下载(推荐)
- 优点是:通过浏览器的默认行为下载,不会阻塞
- 缺点是:必须是同源下载,不过现在都是 webpack 和 nignx 代理,所以推荐这种下载方式
- 简单说说:如果响应头添加
Content-Disposition
,可不使用 download
,两者都可以阻止浏览器默认打开文件,而不是下载文件的行为,但是前者优先级比后者高
export const downLoadFile = (url: string, filename: string) => {
const origin = `/api/${url}`
const aLink = document.createElement("a")
aLink.style.display = "none"
aLink.href = origin
aLink.download = filename
aLink.target = "_black"
aLink.type = "application/octet-stream"
document.body.appendChild(aLink)
aLink.click()
document.body.removeChild(aLink)
}
跨域下载
- 缺点是:要等 blob 封装完成才能下载,如果想实现前端流式下载,可参考fetch 方法
- 优点是:可以携带 Cookie 和请求体 实现动态下载
function getBlob(url: string) {
return new Promise(resolve => {
const xhr = new XMLHttpRequest()
xhr.open("GET", url, true)
xhr.responseType = "blob"
xhr.onload = () => {
if (xhr.status === 200) {
resolve(xhr.response)
}
}
xhr.send()
})
}
function saveAs(blob: Blob, filename: string) {
if (window.navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(blob, filename)
} else {
const anchor = document.createElement("a")
const body = document.querySelector("body")
anchor.href = window.URL.createObjectURL(blob)
anchor.download = filename
anchor.style.display = "none"
body.appendChild(anchor)
anchor.click()
body.removeChild(anchor)
window.URL.revokeObjectURL(anchor.href)
}
}
export async function download(url: string, newFilename: string) {
const blob: Blob = await getBlob(url)
saveAs(blob, newFilename)
}
参考