问题背景
responseHeader
content-disposition: attachment;filename=文件名.xlsx
content-type: application/vnd.ms-excel;charset=utf-8
前端接口请求的时候,设置responseType: 'blob'
,后端接口直接返回的是文件流。
blob格式了,所有需要把blob
转成 string
,用来提示用户下载异常。
代码展示
请求响应拦截处理
// content-disposition: attachment;filename=文件名.xlsx
const contentDisposition = response.headers['content-disposition']
const _fileName = contentDisposition.split('='[1]
const fileType = _fileName.substring(_fileName.lastIndexOf('.'; // .xlsx
const fileName = _fileName.substring(0, _fileName.lastIndexOf('.'; // 文件名
if (fileName && fileType {
return {
data: response.data,
fileName,
fileType
}
}
定义工具函数
因为把blob
转成string
需要用 FileReader
去读取,FileReader
是异步的,所以这里需要用Promise
返回,方便业务组件同步调用
export const downloadFile = (srcData, fileName='下载', fileType='.xls', target='_self' {
var blob = new Blob([srcData]
if (window.navigator && window.navigator.msSaveOrOpenBlob {
// 兼容IE/Edge
window.navigator.msSaveOrOpenBlob(blob, fileName + fileType
} else {
var url = window.URL.createObjectURL(blob
var a = document.createElement('a'
a.href = url
a.target = target
a.style.display = 'none'
a.setAttribute('download', fileName + fileType
document.body.appendChild(a
a.click(
document.body.removeChild(a
window.URL.revokeObjectURL(url // 释放资源
}
}
export const blobToString = (blobData => {
return new Promise((resolve => {
if (blobData instanceof Blob {
const reader = new FileReader(;
reader.readAsText(blobData, 'utf-8'
reader.onload = function ( {
resolve(reader.result || ''
}
} else {
resolve(''
}
}
}
业务组件调用
// 省略部分代码
async down( {
try {
const res = await API(;
const { data, fileName, fileType, code} = res || {}
if (code === -1 {
const result = await blobToString(data
this.$message.error(result
return
}
downloadFile(data, fileName, fileType
} catch (err {
console.log(err
}
}
我是 甜点cc☭
公众号:【看见另一种可能】