使用axios响应拦截器对下载文件统一处理

1,042 阅读1分钟

1. 添加响应拦截器

  1. 在main.js 或者 封装axios文件中添加拦截器
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 下载文件统一处理
  if(response.config.url.indexOf('file/download') > -1){
    const fileName = JSON.parse(response.config.data).fileName
    const blob = response.data
    // IE
    if (IEVersion() > -1) {
      window.navigator.msSaveBlob(blob, fileName);
    } else {
      // 获取 blob 本地文件连接 (blob 为纯二进制对象,不能够直接保存到磁盘上)
      const blobUrl = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = blobUrl;
      a.download = fileName;
      document.body.appendChild(a);
      a.click();
      window.URL.revokeObjectURL(blobUrl);
      document.body.removeChild(a);
    }
  }else{
    return response;
  }
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  });
  1. 创建ExportForm组件
<template>
  <el-dialog
    :title="title"
    :visible.sync="dialogVisible"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    :before-close="handleClose"
    width="350px">
    <el-form :model="form" label-width="80px" label-position="right">
      <el-form-item label="文件类型">
        <el-select v-model="form.fileFormat" size="small">
          <el-option value="xlsx" label="Excel"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="是否压缩">
        <el-radio v-model="form.zipOrNot" :label="1">压缩</el-radio>
        <el-radio v-model="form.zipOrNot" :label="0">不压缩</el-radio>
      </el-form-item>
    </el-form>
    <span slot="footer" class="dialog-footer">
      <el-button type="primary" @click="onConfirm" :loading="loading" size="small">确 定</el-button>
      <el-button size="small" @click="handleClose">取 消</el-button>
    </span>
  </el-dialog>
</template>
<script>
export default {
  data(){
    return {
      loading: false,
      form:{
        zipOrNot: 1,
        fileFormat: 'xlsx',
        operatorMenu: this.operatorMenu,
      }
    }
  },
  props: ['dialogVisible', 'title', 'operatorMenu'],
  methods: {
    onConfirm(){
      this.loading = true
      this.$emit('on-confirm', this.form)
    },
    handleClose(){
      this.loading = false
      this.$emit('on-close')
    }
  }
}
</script>
<style>
.el-dialog__body{
  padding: 20px;
}
</style>>
  1. 在父组件中使用ExportForm组件,
// template
<ExportForm
  ref="exportForm"
  v-bind="exportOptions"
  v-on:on-confirm="handleConfirm"
  v-on:on-close="handleClose"
></ExportForm>

// data
exportOptions: {
    dialogVisible: false,
    title: "导出",
    operatorMenu: "告警历史查询导出",
  },
  
// methods
点击父组件中的导出按钮时,将ExportForm显示
onExport() {
  this.exportOptions.dialogVisible = true;
},
// 确认导出
handleConfirm(pr) {
      const { fileFormat, zipOrNot, operatorMenu } = pr;
      this.$axios({
        url: "/api/warningquery/exportWarningInfo",
        method: "post",
        data: { ...this.queryParams, zipOrNot, fileFormat, operatorMenu },
  }).then((result) => {
    this.$refs.exportForm.handleClose();
    if (result.result === "success") {
      this.$message.success("导出成功,正在下载");
      this.$axios({
        ...commonApi.download,
        data: { fileName: result.fileName, fileType: "export" },
      });
    } else {
      this.$message.error("导出失败");
    }
  });
},
// 取消导出
handleClose() {
  this.exportOptions.dialogVisible = false;
},