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

相关推荐
Avan_菜菜8 小时前
AI 能写代码了,为什么我反而开始要求它先写文档?
前端·github·ai编程
JieE21211 小时前
LeetCode 226. 翻转二叉树|JS 递归超详细拆解,二叉树入门经典题
javascript·算法
JieE21211 小时前
LeetCode 104. 二叉树的最大深度|递归思路超详细拆解
javascript·算法
爱勇宝12 小时前
鸿蒙生态的下半场:开发者不只要能开发,还要能赚钱
android·前端·程序员
IT_陈寒15 小时前
SpringBoot这个自动配置坑我跳了三次
前端·人工智能·后端
kyriewen15 小时前
我用 AI 一周写完了整个项目,上线第一天就崩了——这是我踩过最贵的 5 个坑
前端·javascript·ai编程
Larcher16 小时前
AI Loop:让AI像人一样自主完成任务的核心机制
javascript·人工智能·设计模式
默_笙16 小时前
🃏 JS 只有 8 种数据类型,但我花了 2 天才搞懂 null 和 undefined 的区别
javascript
牧艺16 小时前
从零到协同:构建类飞书在线文档系统的五个技术重难点
前端·人工智能
jump_jump16 小时前
流式 HTML:从 htmx 片段装配到浏览器原生增量渲染
javascript·性能优化·前端工程化