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

相关推荐
东风破_1 小时前
React 受控组件与非受控组件:从一个输入框讲清表单数据流
前端
尤乐娃子1 小时前
进入大厂(厂子大)实习Day12
前端·笔记·实习
程序员爱钓鱼1 小时前
Rust Copy详解:隐式复制与轻量数据类型
前端·后端·rust
四六的六3 小时前
端侧模型多端部署实战:从格式转换到灰度发布,Web 和移动端统一部署流水线
前端·人工智能·大模型·ai编程·ai模型·ai产品·端侧ai
vx-程序开发5 小时前
springboot农产品运输服务平台---附源码75498
java·javascript·spring boot·python·eclipse·django·php
独隅5 小时前
前端离线暂停更新策略:Service Worker 与 PWA 的静默控制实践
前端
妙码生花5 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(五十八):后台系统配置管理实现
前端·后端·go
用户938515635076 小时前
React 受控/非受控组件与 React.memo 性能优化——从本质到实战
前端·javascript·react.js
IT_陈寒6 小时前
Java并行流把我坑惨了:原来不是线程安全的!
前端·人工智能·后端