前端取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。最终实现。

相关推荐
Hyyy36 分钟前
什么是bun?和pnpm有什么区别
前端·面试·bun
To_OC10 小时前
LC 128 最长连续序列:别上来就排序,O (n) 解法才是这题的灵魂
javascript·算法·leetcode
IT_陈寒14 小时前
Vue这个坑我跳了两次,原来问题出在这
前端·人工智能·后端
kyriewen14 小时前
我用 50 行代码重写了 React Router 核心,终于搞懂了前端路由原理
前端·javascript·react.js
WebInfra15 小时前
Rspack 2.1 发布:React Compiler 提速 10 倍!
前端
李明卫杭州15 小时前
CSS 媒体查询详解:一文掌握响应式设计的核心技术
前端
lichenyang45315 小时前
从 H5 按钮到 OpenHarmony 能力调用:我如何理解 ASCF 的运行链路
前端
下家16 小时前
我放弃了 Vue/React,选择自研框架
前端·前端框架
Asize16 小时前
HTML5 Canvas 基础:从按帧动画到 ECharts 数据可视化
前端·javascript·canvas
默_笙17 小时前
🎄 后端给我一堆扁平数据,我 10 行代码把它变成了树
前端·javascript