前端取Content-Disposition中的filename字段与解码(vue)

前言

这个需求其实是根据导出文件来的,导出文件后,后端将文件名存储到请求头中的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 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.use里面

返回的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。最终实现。

相关推荐
pixle08 分钟前
Vue3 Echarts 3D饼图(3D环形图)实现讲解附带源码
前端·3d·echarts
麻芝汤圆42 分钟前
MapReduce 入门实战:WordCount 程序
大数据·前端·javascript·ajax·spark·mapreduce
juruiyuan1112 小时前
FFmpeg3.4 libavcodec协议框架增加新的decode协议
前端
Peter 谭3 小时前
React Hooks 实现原理深度解析:从基础到源码级理解
前端·javascript·react.js·前端框架·ecmascript
周胡杰3 小时前
鸿蒙接入flutter环境变量配置windows-命令行或者手动配置-到项目的创建-运行demo项目
javascript·windows·flutter·华为·harmonyos·鸿蒙·鸿蒙系统
LuckyLay4 小时前
React百日学习计划——Deepseek版
前端·学习·react.js
gxn_mmf4 小时前
典籍知识问答重新生成和消息修改Bug修改
前端·bug
hj10434 小时前
【fastadmin开发实战】在前端页面中使用bootstraptable以及表格中实现文件上传
前端
乌夷5 小时前
axios结合AbortController取消文件上传
开发语言·前端·javascript
晓晓莺歌5 小时前
图片的require问题
前端