axios 下載文件流,請求時攜帶token,並工程化配置

還不瞭解axios的同窗能夠前往這裏,axios的使用說明vue

下面看一下下載文件流注意事項:

一、首先確保後端的是輸出流格式ios

二、axios的服務器響應的數據類型爲responseType:blobelement-ui

三、返回的數據流佔用response.data字段axios

示例:

axios({
        method:'post',//請求方式
        url:'請求地址',
        data:{id:1},//請求參數
        responseType:'blob'//服務器返回的數據類型
    }).then(response=>{
        const content = response.data //返回的內容
        const fileName = '文件.xls'//下載文件名
        download(content,fileName)
    })
    //處理下載流
    function download(content,fileName){
        const blob = new Blob([content]) //建立一個類文件對象:Blob對象表示一個不可變的、原始數據的類文件對象
        const url = window.URL.createObjectURL(blob)//URL.createObjectURL(object)表示生成一個File對象或Blob對象
        let dom = document.createElement('a')//設置一個隱藏的a標籤,href爲輸出流,設置download
        dom.style.display = 'none'
        dom.href = url
        dom.setAttribute('download',fileName)//指示瀏覽器下載url,而不是導航到它;所以將提示用戶將其保存爲本地文件
        document.body.appendChild(dom)
        dom.click()
    }
複製代碼

工程化下對axios的配置以下

requestDownload.js
import axios from 'axios'
import { Message } from 'element-ui'
import store from '@/store'

// create an axios instance
const service = axios.create({
  baseURL: '請求地址', // process.env.VUE_APP_BASE_API; url = base url + request url;
  withCredentials: true,//表示跨域請求時是否須要使用憑證
  responseType: 'blob' //接收返回的類型
})
/** * HTTP方法 */

// request interceptor
service.interceptors.request.use(
  config => {
    // do something before request is sent
    if (store.getters.token) {
      // let each request carry token --['X-Token'] as a custom key.
      // please modify it according to the actual situation.
      config.headers['token'] = store.getters.token
    }
    return config
  },
  error => {
    // do something with request error
    Message({
      message: '文件不存在',
      type: 'error',
      duration: 5 * 1000
    }) // for debug
    return Promise.reject(error)
  }
)

// response interceptor
service.interceptors.response.use(
  /** * If you want to get information such as headers or status * Please return response => response */

  /** * Determine the request status by custom code * Here is just an example * You can also judge the status by HTTP Status Code. */
  response => {
    if (!response.data) {
      return Promise.reject('文件不存在')
    } else {
      return response.data
    }
  },
  error => {
    // console.log('err' + error) // for debug
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

export default service

複製代碼

requestDownload.js這種設置存在一個問題:全部的返回都是以blob方式返回的,若出現token超時的狀況,將沒法校驗;後端

改進方法以下:

一、request.js
....request配置....

// response interceptor
service.interceptors.response.use(
 response => {
   const res = response.data
   if (response.config.responseType === 'blob') {
     return res
   }
   //假設res.code=0時,返回結果爲succuss , res.code = 9008爲token超時
   if (res.code === 9008  ) {
       Message({
         message: '登陸超時,請從新登陸',
         type: 'error',
         duration: 5 * 1000
       })
     return Promise.reject(error.message)
   } else {
     return res
   }
 },
 error => {
   // console.log('err' + error) // for debug
   Message({
     message: error.message,
     type: 'error',
     duration: 5 * 1000
   })
   return Promise.reject(error)
 }
)

export default service
複製代碼
二、後端增長校驗token超時的方法
三、請求接口文件:requestDownload.js 封裝請求方法
import request from '@/utils/request'

async function requestDownload({ url, method, data }) {
 await request({
   url: '校驗超時連接',
   method: 'post'
 })
 return request({
   url,
   method,
   data,
   responseType: 'blob'//必填項
 })
}
export default requestDownload
複製代碼
公共方法文件/util/index.js中增長,處理流的方法
//處理下載流
    export function download(content,fileName){
        const blob = new Blob([content]) //建立一個類文件對象:Blob對象表示一個不可變的、原始數據的類文件對象
        const url = window.URL.createObjectURL(blob)//URL.createObjectURL(object)表示生成一個File對象或Blob對象
        let dom = document.createElement('a')//設置一個隱藏的a標籤,href爲輸出流,設置download
        dom.style.display = 'none'
        dom.href = url
        dom.setAttribute('download',fileName)//指示瀏覽器下載url,而不是導航到它;所以將提示用戶將其保存爲本地文件
        document.body.appendChild(dom)
        dom.click()
    }
複製代碼
接口示例 proAdd.js中增長下載接口
import requestDownload from '@/utils/requestDownload'
export function exportFile(data) {
  return requestDownload({
    url: '/excel/excelDownLoad',
    method: 'post',
    data:data
  })
}
複製代碼
使用示例 exportExcelBtn.vue中添加調用方法
import { exportFile } from '@/api/**.js'
import { download } from '@/utils/index.js'
 exportFile({ id : 1 }).then(result => {
        download(result, '模板文件.xlsx')
      })
複製代碼

文件結構圖

相關文章
相關標籤/搜索