【post请求下载文件流】如何使用post请求下载文件流 blob
最近有个需求,做文件的下载。其实下载没什么要特别说的,之前都是用的get请求,这次不同,后台用的post请求,返回的是数据流,这种post请求下载文件的方式倒是没怎么弄过。记录一下。
接口
接口地址为: /file/download/${id}
前端请求这里要注意(这个是重点)设置 responseType: 'blob'。
我这里用 axios 请求,代码如下:
import {axios} from '../../config';
import {BaseURL} from "@/serviceConfig";
// 附件下载
export const download = id => axios({
method: 'post',
url: `${BaseURL}/file/download/${id}`, // 请求地址
responseType: 'blob'
});
然后这样请求回来的结果就是blob:
// 附件点击下载
async downloadDoc (id) {
let res = await download(id);
let blob = res.data;
let url = window.URL.createObjectURL(blob);
let eleLink = document.createElement('a');
eleLink.href = url
eleLink.download = name
document.body.appendChild(eleLink)
eleLink.click()
window.URL.revokeObjectURL(url)
},
const exportExtension = (params) => {
return http({
method: 'get',
url: '/vsts/ui/v1/channelExtension/export',
params,
responseType: 'blob'
})
}
download(name, blob) {
try {
const urlObject = window.URL || window.webkitURL
const link = document.createElement('a')
link.href = urlObject.createObjectURL(blob)
link.download = name
link.click()
} catch (err) {
console.log(err)
}
},
exportExtension({
regionId: this.regionId,
cascade: this.cascade,
...params,
}).then(res => {
console.log(res)
if (res && res.data) {
const contentDisposition = res.headers['content-disposition']
// Content-Disposition 响应头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地
if (contentDisposition && contentDisposition.includes('attachment')) {
let filename
if (contentDisposition.includes('filename')) {
filename = decodeURI(contentDisposition.split(';')[1].replace('filename=', '')) // decodeURI() 函数可对 encodeURI() 函数编码过的 URI 进行解码
} else {
filename = new Date().getTime()
}
if (window.navigator.msSaveOrOpenBlob) {
// 兼容IE浏览器
window.navigator.msSaveOrOpenBlob(res.data, filename)
} else {
this.download(filename, new Blob([res.data], { type: '' }))
}
}
}
})
拓展
这里出现了不怎么常用的方法:window.URL.createObjectURL(blob) 和 window.URL.revokeObjectURL(url)。
window.URL.createObjectURL(blob)
mdn文档: URL.createObjectURL() - Web API 接口参考 | MDN
每次你调用window.URL.createObjectURL(),就会产生一个唯一的对象URL。结果如下:
blob:http://xxxxxx <文件地址>
获得这个地址之后,去开起下载任务。
window.URL.revokeObjectURL(url)
当文档关闭时,它们会自动被释放。如果你的网页要动态使用它们,你需要显式调用 window.URL.revokeObjectURL()来释放它们。
就这样记录一下。