axios 下载文件使用mockjs会使文件异常

问题描述

  1. 跟后台做excel导出的功能,发现用postman 和 swagger 调用下载接口,都是可以正常下载和打开
  2. 但是自己用axios下载,发现下载的文件变大了(实际是7.6K 变为11K),并且打开文件提示“文件已损坏或者无法打开”

查找资料

  1. axios下载excel踩坑记录(导出Excel总是报格式错误而且乱码)

自己错误的原因

因为自己方便开发,使用了Mockjs,导致下载excel出了问题

在这里插入图片描述

在这里插入图片描述

代码说明

/*
 * API
 * dev: 开发环境    test: 测试环境    prod: 生产环境
 * */
const oDomains = {
  // 默认ajax地址
  base: {
    dev: '/' + process.env.VUE_APP_CONTEXT,
    test: '/' + process.env.VUE_APP_CONTEXT,
    prod: '/' + process.env.VUE_APP_CONTEXT
  },
  img: {
    // dev: 'http://localhost:1709',
    dev: 'http://10.192.202.53:9101/' + process.env.VUE_APP_CONTEXT,
    test: '/' + process.env.VUE_APP_CONTEXT,
    prod: '/' + process.env.VUE_APP_CONTEXT
  }
}
let ENV_API = 'dev'
if (process.env.NODE_ENV === 'production') {
  ENV_API = 'prod'
}
// console.log('config.js env:', ENV_API)
// ajax default
const ajaxCtx = {}
for (const _key in oDomains) {
  ajaxCtx[_key] = oDomains[_key][ENV_API]
}
// console.log(ajaxCtx)
export { ajaxCtx }
import axios from 'axios'
import { Message } from 'element-ui'
import { ajaxCtx } from '@/api/config.js'
const REQUEST_SUCCESS = 0
const REFRESH_BY_HEADER = 1

const http = axios.create({
  timeout: 20000,
  withCredentials: true,
  headers: { 'X-Requested-With': 'XMLHttpRequest' }
})


// 相应拦截器
http.interceptors.response.use(function (response) {
  if (response.request.responseURL.indexOf('/api/analysis/api/analysis/export') > 0) {
    // 返回的是数据流,实现文件下载
    if (response.headers['content-type'].indexOf('octet-stream') !== -1) {
      return Promise.resolve({
        data: response.data
      })
    } else { // 返回的是JSON
      const tips = '导出异常'
      var b = new Blob([response.data])
      var r = new FileReader()
      r.readAsText(b, 'utf-8')
      r.onload = function () {
        Message.info(JSON.parse(r.result).msg)
      }
      return Promise.reject(tips)
    }
  }

  // 请求多语言的json文件
  if (/.*\.json$/.test(response.config.url)) {
    return response
  }

  // 根据响应数据判断是否登录过期
  if (response.data.errorCode === REFRESH_BY_HEADER) {
    let refreshUrl = response.headers['refresh-url'].split('?')[0]
    refreshUrl = refreshUrl + '?service=' + location.protocol + '//' + location.host + location.pathname + encodeURIComponent(location.search)
    location.href = refreshUrl
    return
  }

  // 对错误进行统一处理
  if (response.data.code !== REQUEST_SUCCESS) {
    if (!response.config.noMsg && response.data.msg) {
      Message.error(response.data.msg)
    }
    return Promise.reject(response)
  } else if (response.data.code === REQUEST_SUCCESS && response.config.successNotify && response.data.msg) {
    // 弹出成功提示
    Message.success(response.data.msg)
  }
  return Promise.resolve({
    code: response.data.code,
    msg: response.data.msg,
    data: response.data.data
  })
}, function (error) {
  if (error.message.indexOf('timeout') > -1) {
    // 多语言需要自己在项目中配置
    Message.error('请求超时,请重试!')
  }

  return Promise.reject(error)
})

// 请求拦截器
http.interceptors.request.use(function (config) {
  // 模式,用来区分 开发环境 和 发布环境
  if (config.mode && ajaxCtx[config.mode]) {
    config.baseURL = ajaxCtx[config.mode]
  }
  return config
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error)
})

export default http
export const exportService = (data) => {
  return http({
    method: 'post',
    data,
    responseType: 'arraybuffer',
    url: '/api/analysis/api/analysis/export',
    mode: 'base'
  })
}
// 导出功能
exportDetail () {
  API.exportService(this.cearchCondition).then(res => {
    const blob = new Blob([res.data], {
      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'
    })
    const downloadElement = document.createElement('a')
    const href = window.URL.createObjectURL(blob) // 创建下载的链接
    downloadElement.href = href
    downloadElement.download = new Date().getTime() + '.xls' // 下载后文件名
    document.body.appendChild(downloadElement)
    downloadElement.click() // 点击下载
    document.body.removeChild(downloadElement) // 下载完成移除元素
    window.URL.revokeObjectURL(href) // 释放blob对象
  })
},
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页