Axios post 文件下载

javascript 代码如下

 /* 下载方法 */
downFile(blob, fileName) {
 // 非IE下载
 if ('download' in document.createElement('a')) {
   let link = document.createElement('a');
   link.href = window.URL.createObjectURL(blob); // 创建下载的链接
   link.download = fileName; // 下载后文件名
   link.style.display = 'none';
   document.body.appendChild(link);
   link.click(); // 点击下载
   window.URL.revokeObjectURL(link.href); // 释放掉blob对象
   document.body.removeChild(link); // 下载完成移除元素
 } else {
   // IE10+下载
   window.navigator.msSaveBlob(blob, fileName);
 }
},
downloadFile(url, data) {
    let requestData = Object.assign({}, data, {
      accessToken: sessionStorage.getItem('accessToken')
    });

    // 响应类型:arraybuffer, blob
    axios.post(url, requestData, {responseType: 'blob'}).then(resp => {
      let headers = resp.headers;
      let contentType = headers['content-type'];

      console.log('响应头信息', headers);
      if (!resp.data) {
        console.error('响应异常:', resp);
        return false;
      } else {
        console.error('下载文件:', resp);
        const blob = new Blob([resp.data], {type: contentType});

        const contentDisposition = resp.headers['content-disposition'];
        let fileName = 'unknown';
        if (contentDisposition) {
          fileName = window.decodeURI(resp.headers['content-disposition'].split('=')[1]);
        }
        console.log('文件名称:', fileName);
        this.downFile(blob, fileName);
      }
    }).catch(function (error) {
        console.log(error);
    });
}

注意: 两种responseType的区别

  1. arrarybuffer: 响应的 data 如下图

    image.png

  2. blob:响应的 data 如下图

    image.png

遇到的坑:

  1. 无法获取响应头(即无法获取文件名): content-disposition

In case of CORS requests, browsers can only access the following response headers by default:

  • Cache-Control
  • Content-Language
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma
    If you would like your client app to be able to access other headers, you need to set the Access-Control-Expose-Headers header on the server: Access-Control-Expose-Headers: Access-Token, Uid

解决方法1:

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

解决方法2:在跨域中设置 exposeHeaders

@Bean
CorsConfigurationSource corsConfigurationSource() {

    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowCredentials(true);
    configuration.setAllowedOrigins(Arrays.asList(FRONT_END_SERVER));
    configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
    configuration.setAllowedHeaders(Arrays.asList("X-Requested-With","Origin","Content-Type","Accept","Authorization"));

    // This allow us to expose the headers
    configuration.setExposedHeaders(Arrays.asList("Access-Control-Allow-Headers", "Authorization, x-xsrf-token, Access-Control-Allow-Headers, Origin, Accept, X-Requested-With, " +
            "Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers"));

    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}
  1. 下载的文件名乱码
    将文件名进行 utf-8 编码
String fileName = URLEncoder.encode("导入成交比模板.xls", "UTF-8");
response.setHeader("Content-Disposition", "attachment;filename="+fileName);

后端主要 java 代码如下:

// 题头
List headNameList = statisticsService.getExcelHeader("downLoad");
// 生成导入模板
HSSFWorkbook wb = ExcelUtil.exportTemplate("导入成交比模板", null, headNameList);
// 设置导出格式为Excel
response.setContentType("application/vnd.ms-excel");
// 设置文件名并解决中文乱码

String fileName = URLEncoder.encode("导入成交比模板.xls", "UTF-8");
response.setHeader("Content-Disposition", "attachment;filename="+fileName);
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");

response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "No-cache");
response.setDateHeader("Expires", 0);

// 声明输出流
OutputStream ouputStream = response.getOutputStream();
// 输出文件
wb.write(ouputStream);
ouputStream.flush();
ouputStream.close();

参考连接:

  1. https://stackoverflow.com/questions/37897523/axios-get-access-to-response-header-fields
  2. Access-Control-Expose-Headers
  3. https://www.kancloud.cn/yunye/axios/234845

你可能感兴趣的:(Axios post 文件下载)