日志下载,后端返回文件流,前端如何处理?

287 阅读2分钟

场景:

实现日志下载功能时,后端返回文件流,如下:

image.png

解决办法:

第一步、设置responseType为'blob'

指定服务器响应的数据类型为“blob”,设置成功后,服务器响应的数据将被视为一个Blob对象,而不是默认的字符串或JSON对象.

Blob对象表示了一段不可变的原始数据,它常常用于表示从文件系统读取的数据,或者用于处理二进制HTTP响应,例如下载文件或处理图片、视频等。

代码示例如下:

fetch(url, {  
  method: 'GET',  
  responseType: 'blob'  
})

加入responseType: 'blob' 后,返回的数据样式为:

image.png

第二步、使用浏览器提供的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)
})