前言
这个需求其实是根据导出文件来的,导出文件后,后端将文件名存储到请求头中的headers里了,那么前端需要从headers里的Content-Disposition里面取到并解码。
第一步:新增getFileRequest.js
因为涉及到拿去接口中的headers中数据,为了避免修改全局的request.js文件而引发的一系列问题,我新建了一个一个新的request.js叫getFileRequest.js专门处理关于文件上传的问题。具体内容如下(vue2):
javascript">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 requeststimeout: 1000* 60* 5 // request timeout
})// request interceptor
service.interceptors.request.use(config => {// do something before request is sent && !config.noFormif (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 errorconsole.log(error) // for debugreturn Promise.reject(error)}
)// response interceptor
service.interceptors.response.use(response => {// token存储const { headers, request: { responseURL } } = responseif (responseURL.includes('auth/login')) {store.dispatch('user/changeSomething', { token: headers.authorization })setToken(headers.authorization)}// ============const res = responsereturn res},error => {console.log(error);console.log('err' + error) // for debugMessage({message: error.message,type: 'error',duration: 5 * 1000})return Promise.reject(error)}
)export default service
主要修改部分其实就一处,就是在service.interceptors.response.us
e里面
返回的res
是全部信息,而不是res.data
。
第二步:对返回数据进行请求头的获取与解码
这里我截取一部分代码
javascript">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
。最终实现。