ajax下载文件

本文探讨了如何通过Ajax实现文件下载。重点强调后端直接返回字节流时的注意事项,包括设置responseType与headers的位置,确保文件名包含后缀,并且提醒在操作结束后释放资源以防止内存泄漏。此外,还提到了当后端返回的字节流被base64编码的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

后端直接返回字节流

this.request(Object.assign({ responseType: 'blob' }, options), params).then((res) => {
	if (!res?.data) {
        message('未能获取文件流')
        return Promise.reject()
    }
    try {
        let contentDisposition = res.headers['content-disposition'].replace(/['"]/g, '')
        // 文件名需要url编码,才能读取,否则取到的是乱码
        let patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*')
        let result = patt.exec(contentDisposition)
        let filename = decodeURI(result[1])
        const url = URL.createObjectURL(new Blob([res.data]))
        const a = document.createElement('a')
        a.style.display = 'none'
        a.href = url
        a.setAttribute('download', filename)
        if (typeof a.download === 'undefined') {
            a.setAttribute('target', '_blank')
        }
        document.body.appendChild(a)
        a.click()
        // 启动下载后需要释放资源
        document.body.removeChild(a)
        URL.revokeObjectURL(url)
    } catch (error) {
        console.log(error)
        message('可能浏览器版本低,请升级或更换浏览器后重试')
        return Promise.reject()
    }
    return Promise.resolve()
})

注意事项

  1. responseType要和headers同级,不能放在headers里
  2. 后端需要设置content-disposition并且文件名要带后缀
  3. 每次结束一定要调用URL.revokeObjectURL,避免内存泄漏

后端返回字节流被base64编码

当后端不是以字节数组的形式直接塞入response时,字节数组会自动转为base64

this.request(Object.assign({ responseType: 'blob' }, options), params).then((res) => {
    try {
        const filename = res.data.filename
        const base64Str = atob(res.data.file) // res.data.file为base64字符串
	    const len = base64Str.length
	    const bytes = new Int8Array(len)
	    for (let i = 0; i < len; i++) {
	        bytes[i] = base64Str.charCodeAt(i)
	    }
        const url = URL.createObjectURL(new Blob([bytes]))
        const a = document.createElement('a')
        a.style.display = 'none'
        a.href = url
        a.setAttribute('download', filename)
        if (typeof a.download === 'undefined') {
            a.setAttribute('target', '_blank')
        }
        document.body.appendChild(a)
        a.click()
        // 启动下载后需要释放资源
        document.body.removeChild(a)
        URL.revokeObjectURL(url)
    } catch (error) {
        console.log(error)
        message('可能浏览器版本低,请升级或更换浏览器后重试')
        return Promise.reject()
    }
    return Promise.resolve()
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值