场景:
实现日志下载功能时,后端返回文件流,如下:
解决办法:
第一步、设置responseType为'blob'
指定服务器响应的数据类型为“blob”,设置成功后,服务器响应的数据将被视为一个Blob对象,而不是默认的字符串或JSON对象.
Blob对象表示了一段不可变的原始数据,它常常用于表示从文件系统读取的数据,或者用于处理二进制HTTP响应,例如下载文件或处理图片、视频等。
代码示例如下:
fetch(url, {
method: 'GET',
responseType: 'blob'
})
加入responseType: 'blob' 后,返回的数据样式为:
第二步、使用浏览器提供的blob 对象和 URL.createObjectURL() 方法,利用a标签实现下载。
下面,我们将通过 new Blob([data], { type: type }) 创建blob对象,通过URL.createObjectURL() 创建一个代表这个Blob对象的URL,接着将这个url设置为a链接的href属性。
同时,将a链接的download属性设置为要保存的文件名,并模拟点击链接元素,启动下载。
下载完成后,通过URL.revokeObjectURL()释放url对象,以便浏览器可以回收这个对象的内存。
完整代码示例如下:
axios({
url: "",
method: "get", // 或post
responseType: "blob",
params: {}
}).then(res => {
const link = document.createElement("a")
link.style.display = "none"
// 此处的res为返回的Blob对象,上文中的{size: 252, type:"application/octet-stream"}
/**
* type的值由下载的文件类型决定,excel文件为“application/xlsx”
* 当不确定文件的实际类型时,服务器可能会设置content-type为'application/octet-stream',
* 在 HTTP 响应中通常用于告诉客户端它应该下载并保存返回的数据,而不是尝试解析或显示它。
*/
const blob = new Blob([res], { type: 'application/octet-stream' })
const url = URL.createObjectURL(blob)
link.href = url
link.download = '文件名称.文件类型'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
URL.revokeObjectURL(url)
})