• vue通过接口下载文件的封装及使用


    1、先封装axios请求(request.js)

    import axios from 'axios'
    import { Message, Loading } from 'element-ui'
    import Vue from 'vue'
    axios.defaults.withCredentials = true
    let loading = null // 定义loading变量
    const startLoading = () => {
      loading = Loading.service({
        lock: true,
        text: '正在玩命加载中……',
        background: 'rgba(0, 0, 0, 0.7)'
      })
    }
    // 结束 取消loading加载
    const endLoading = () => {
      loading.close()
    }
    
    let needLoadingRequestCount = 0 // 声明一个变量
    
    const showFullScreenLoading = () => {
      if (needLoadingRequestCount === 0) { // 当等于0时证明第一次请求 这时开启loading
        startLoading()
      }
      needLoadingRequestCount++ // 全局变量值++
    }
    
    const tryHideFullScreenLoading = () => {
      if (needLoadingRequestCount <= 0) return // 小于等于0 证明没有开启loading 此时return
      needLoadingRequestCount-- // 正常响应后 全局变量 --
      if (needLoadingRequestCount === 0) { // 等于0 时证明全部加载完毕 此时结束loading 加载
        endLoading()
      }
    }
    
    // import store from '../store'
    Vue.prototype.$message = Message
    const service = axios.create({
      // timeout: 50000, // request timeout
      baseURL: process.env.VUE_APP_BASE_API,
      withCredentials: true,
      crossDomain: true
    })
    // request interceptor
    service.interceptors.request.use(
      config => {
        config.headers.Authorization = window.localStorage.getItem('token')
        config.headers.platform = window.sessionStorage.getItem('platform')
        showFullScreenLoading()
        return config
      },
      error => {
        Promise.reject(error)
      }
    )
    service.interceptors.response.use(
      response => {
        const res = response.data
        if (res.code) {
          if (res.code == 1000) {
            tryHideFullScreenLoading()
            return Promise.resolve(res)
          } else if (res.code == 1002) {
            window.sessionStorage.clear()
            Vue.prototype.$message('请登录')
            tryHideFullScreenLoading()
            return Promise.reject(res)
          } else {
            Vue.prototype.$message.warning(res.msg)
            tryHideFullScreenLoading()
            return Promise.reject(res)
          }
        } else {
          tryHideFullScreenLoading()
          return Promise.resolve(response)
        }
      }, error => {
        tryHideFullScreenLoading()
        Vue.prototype.$message(error + '请求超时')
      })
    
    export default service
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82

    2、在针对接口返回的数据流进行2次封装(http.js)

    import request from '../utils/request'
    import { Toast } from 'vant'
    let loading = null // 定义loading变量
    const fileExport = (url, fileName, params) => {
      loading = Toast.loading({
        message: '加载中...',
        forbidClick: true,
        duration: 0
      })
      return request.post(url, params, {
        responseType: 'blob',
        isBlobRequest: true
      }).then(res => {
        // console.log(res, 'res')
        // 设置responseType: 'blob',导致返回数据是Blob类型数据,需要转回JSON格式,展示接口请求失败返回的msg信息
        // 创建一个 FileReader 对象
        const reader = new FileReader()
        // 设置当读取完成时的回调函数
        reader.onload = function (event) {
          try {
            // 尝试解析 JSON 数据
            const jsonData = JSON.parse(event.target.result)
            Toast.fail(jsonData.msg)
            // console.log('JSON 数据解析成功:', jsonData)
            // 此处可以进行成功后的操作
          } catch (error) {
            const blob = new Blob([res.data])
            if ('download' in document.createElement('a')) { // 非IE下载
              const elink = document.createElement('a')
              if (fileName) {
                elink.download = fileName
              } else {
                const fileNameEdit = res.headers['content-disposition']
                // console.log(fileNameEdit, 'fileNameEdit')
                const extractedFileName = fileNameEdit.match(/filename="([^"]+)"/)[1]
                elink.download = extractedFileName
              }
              elink.style.display = 'none'
              elink.href = URL.createObjectURL(blob)
              document.body.appendChild(elink)
              elink.click()
              URL.revokeObjectURL(elink.href) // 释放URL 对象
              document.body.removeChild(elink)
            } else { // IE10+下载
              navigator.msSaveBlob(blob, fileName)
            }
            loading.close()
            // console.log('JSON 数据解析失败:', error)
            // 此处可以进行解析失败后的操作
          }
        }
        // 开始读取 Blob 数据
        reader.readAsText(res.data)
      }).catch(e => {
        console.error(e)
      })
    }
    
    export { fileExport }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    3、api接口文件(material.js)

    import { fileExport } from '../utils/http'
    // 资料包打包下载
    export const materialCompress = (fileName, params) => {
      fileExport('/material/compress', fileName, params)
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4、在界面中使用

    <template>
    	<div>
    	...
    	<div class="packageDownload">
          <van-button type="info" size="large" @click="packageDownload">打包下载</van-button>
        </div>
    	</div>
    </template>
    
    <script>
    import {materialCompress} from '../api/material'
    export default {
    	...
    	methods: {
    	    packageDownload () {
    	      let name = '文件名称'+'.文件格式'
    	      materialCompress(name, {
    	        material_id: this.material_id
    	      })
    	    }
    	}
    }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
  • 相关阅读:
    IIC通信
    OkHttp - 拦截器篇
    休闲卤味的商业江湖里,周黑鸭的巨变与出路
    基于蚁群算法的时延Petri网(ACOTPN)路径规划算法(Matlab代码实现)
    计算机毕业设计(附源码)python筑柏机器人培训中心管理系统
    Python机器视觉--OpenCV入门--机器视觉与OpencCV用途简介
    简单的反弹shell到全交互式shell
    「PAT甲级真题解析」Advanced Level 1005 Spell It Right
    4、QT中的网络编程
    计算机毕业设计(83)php小程序毕设作品之服务预约家政小程序系统
  • 原文地址:https://blog.csdn.net/rhcjqmm666/article/details/133748568