vue请求接口返回文件流并进行下载

vue项目,有两种方式实现请求接口返回文件流并进行下载:

第一种:使用a标签的特性,使用链接实现

第二种:下载文件流的方式

一。前端实现静态文件的下载

1.将要下载的静态文件放入项目的public文件夹中,如下图,test.pptx文件

vue请求接口返回文件流并进行下载_第1张图片

2.代码中添加a标签:
下载
3.打包之后test.pptx文件就会放在打包文件dist中,如下图:

vue请求接口返回文件流并进行下载_第2张图片

二。当接口为get请求时,可以使用a标签实现动态文件的下载

这里使用的是前后端合作的方式

下载动态文件流就是文件存储在后台,需要使用接口请求,来实现文件的下载

1.配置项目的Base url
const URL_GLOBAL = {
    development: "http://localhost",
    production: "https://baidu.com",

    developmentPort: ":8888/hhh",
    productionPort: "/abc",
}

this.globalURL = URL_GLOBAL[process.env.NODE_ENV] + URL_GLOBAL[process.env.NODE_ENV + 'Port'];
2.当接口为get请求时,可以使用a标签,将接口拼接在href中,如果有参数可以直接拼接在url后面
          Download Excel
          
3.点击页面中a标签的按钮,就可以将文件下载到本地了

三。当接口为post请求时,就不能使用a标签了,使用下载文件流的方式实现

 1.配置项目的Base url
const URL_GLOBAL = {
    development: "http://localhost",
    production: "https://baidu.com",

    developmentPort: ":8888/hhh",
    productionPort: "/abc",
}

this.globalURL = URL_GLOBAL[process.env.NODE_ENV] + URL_GLOBAL[process.env.NODE_ENV + 'Port'];
2.使用按钮触发下载
Download Excel
3.引入axios
import axios from "axios";
4.实现接口请求,下载文件流

 注意必坑:

当获取后端设置的响应头字段时,比如设置的文件名称或者自定义的参数时,

要在后端设置响应头,必须要设置以下代码,来公开自定义响应头,否则前端拿不到响应头中对应的数据:

response.setHeader("Access-Control-Expose-Headers","content-disposition");

    exportExcel() {
      let params = {
        type: 'code'
      }
      //下载文件流
      let url = this.globalURL + '/code/getcode'
      axios.post(url,params,{
        responseType:'blob'
      }).then(res => {
        const name = res.headers['content-disposition'];
        let fileName = '';
        if (name) {
          const str1 = name.replace(' ', '');
          const arr1 = str1.split(';');
          arr1.some(item => {
            if (item.indexOf('filename') != -1) {
              fileName = item.split('=')[1];
            }
            return item.indexOf('filename') != -1;
          });
          if (fileName === ''){
            fileName = 'excel.xlsx'
          }
        } else {
          fileName = 'excel.xlsx'
        }

        try {
          let objectUrl1 = window.URL.createObjectURL(new Blob([res.data]));
          let elink = document.createElement('a');
          elink.setAttribute('download', decodeURI(decodeURI(fileName)));
          elink.style.display = 'none';
          elink.href = objectUrl1;
          document.body.appendChild(elink);
          elink.click();
          document.body.removeChild(elink);
          window.URL.revokeObjectURL(elink.href);
        }catch (err){
          this.$message.warning('download error!')
        }
      })
    },

四.如果想要下载的接口request配置headers,a标签就不能满足需求了,需要使用下载文件流的方式实现

这种方式,不管接口是get请求,还是post请求都可以用

1.配置request.js文件,封装axios
const service = axios.create({
  baseURL: URL_GLOBAL[process.env.NODE_ENV] + URL_GLOBAL[process.env.NODE_ENV +'Port'],
  timeout: 300000,
});

配置请求头,将需要的信息存储在请求头中

service.interceptors.request.use(
    async (config)=>{
        if (process.env.NODE_ENV !== 'development'){
            config.headers['username'] = 'annie'
        }
        return config
    },
    error => {
        Promise.reject(error)
    }
)
2.在vue文件中,引入封装好的axios
import fetch from "../request"

使用按钮触发下载事件

Download excel
3.实现接口请求,下载文件流

注意必坑:

当获取后端设置的响应头字段时,比如设置的文件名称或者自定义的参数时,

要在后端设置响应头,必须要设置以下代码,来公开自定义响应头,否则前端拿不到响应头中对应的数据:

response.setHeader("Access-Control-Expose-Headers","fileName");

详细了解Access-Control-Expose-Headers:Access-Control-Expose-Headers 响应报头、跨域 公开响应头_withexposedheaders-CSDN博客

接口请求

downloadFiles() {
      return new Promise((resolve, reject) => {
          fetch({
              url: "/down/download",
              method: "get",
              params: {
                  id: '222',
              },
              responseType: "blob",
          })
              .then((res) => {
                // 获取后端设置的响应头字段时,比如设置的文件名称或者自定义的参数时,
                  // 在后端设置响应头时,必须要设置以下代码,来公开自定义响应头,否则前端拿不到:
                  // response.setHeader("Access-Control-Expose-Headers","fileName");
                  const fileName = res.headers["filename"];
                  const blob1 = res.data;
                  console.log(blob1)
                  console.log(fileName)
                  if ("download" in document.createElement("a")) {
                      const elink = document.createElement("a");
                      elink.download = decodeURIComponent(fileName);
                      elink.style.display = "none";
                      elink.href = URL.createObjectURL(blob1);
                      document.body.appendChild(elink);
                      elink.click();
                      console.log(elink)
                      URL.revokeObjectURL(elink.href); // 释放URL 对象
                      document.body.removeChild(elink);
                  } else {
                      // IE10+下载
                      navigator.msSaveBlob(blob1, fileName);
                  }
              })
              .catch((err) => {
                  reject(err);
              });
      });
    },

你可能感兴趣的:(Vue,JavaScript,前端,前端,javascript,vue)