前端取Content-Disposition中的filename字段与解码(vue)
前言
这个需求其实是根据导出文件来的,导出文件后,后端将文件名存储到请求头中的headers里了,那么前端需要从headers里的Content-Disposition里面取到并解码。
第一步:新增getFileRequest.js
因为涉及到拿去接口中的headers中数据,为了避免修改全局的request.js文件而引发的一系列问题,我新建了一个一个新的request.js叫getFileRequest.js专门处理关于文件上传的问题。具体内容如下(vue2):
import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken, setToken } from '@/utils/auth'
// create an axios instance
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests
timeout: 1000* 60* 5 // request timeout
})
// request interceptor
service.interceptors.request.use(
config => {
// do something before request is sent && !config.noForm
if (config.data) {
const dataForm = new FormData()
for (const key in config.data) {
dataForm.append(key, config.data[key])
}
config.data = dataForm
}
// =====
if (getToken()) {
config.headers['Authorization'] = getToken()
}
return config
},
error => {
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
)
// response interceptor
service.interceptors.response.use(
response => {
// token存储
const { headers, request: { responseURL } } = response
if (responseURL.includes('auth/login')) {
store.dispatch('user/changeSomething', { token: headers.authorization })
setToken(headers.authorization)
}
// ============
const res = response
return res
},
error => {
console.log(error);
console.log('err' + error) // for debug
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service
主要修改部分其实就一处,就是在service.interceptors.response.us
e里面
返回的res
是全部信息,而不是res.data
。
第二步:对返回数据进行请求头的获取与解码
这里我截取一部分代码
async exportTemplate(bizCode) {
this.loading = true;
try {
const res = await this.$api.xxx({
xxx
},
{
responseType: 'blob' // 确保响应类型为 blob
});
const contentDisposition = res?.headers['content-disposition'];
let fileName = '模板.xlsx'; // 默认文件名
if (contentDisposition && contentDisposition.indexOf('fileName=') !== -1) {
// 解码文件名
fileName = decodeURIComponent(contentDisposition.split('fileName=')[1].replace(/['"]/g, ''));
}
const link = document.createElement("a");
let blob = new Blob([res.data]);
link.style.display = "none";
link.href = URL.createObjectURL(blob);
link.setAttribute("download", fileName);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
} catch (e) {
console.log(e);
} finally {
this.loading = false;
}
首先我通过调用res?.header['content-disposition']
获取到全部的content-disposition信息,然后再判断这个信息是否存在且能捕获到fileName
,如果存在且能够捕获到,那么进行文件名的解码,具体用的就是decodeURIComponent
。最终实现。