由于采用前后端完全分离架构,后端采用Laravel,前端采用react,交互通过axios库使用ajax进行,这样就导致无法get请求下载文件。

文件下载通常分为两类:

  • 一类是真是存在于服务器上面的文件
  • 一类是后端动态生成的字节流文件

为了解决这两者的下载问题我自定义了助手方法来配合axios实现文件下载。

/**
 * js 文件下载
 *
 * DownloadHelper.js
 * import downloadHelper from './DownloadHelper';
 */

/**
 * http文件下载
 *
 * use:
 * downloadHelper.downloadUrl(response.data);
 *
 * @param url
 */
const downloadUrl = url => {
    let iframe = document.createElement('iframe');
    iframe.style.display = 'none';
    iframe.src = url;
    iframe.onload = function () {
        document.body.removeChild(iframe)
    };
    document.body.appendChild(iframe)
};

/**
 * 获取字节流文件
 *
 * use:
 * var blob = new Blob([response.data], {type: 'application/vnd.ms-excel'});
 * var fileName = '文件名称.csv';
 * downloadHelper.downFile(blob, fileName);
 *
 * @param blob
 * @param fileName
 */
function downFile(blob, fileName) {
    if (window.navigator.msSaveOrOpenBlob) {
        navigator.msSaveBlob(blob, fileName);
    } else {
        var link = document.createElement('a');
        link.href = window.URL.createObjectURL(blob);
        link.download = fileName;
        link.click();
        window.URL.revokeObjectURL(link.href);
    }
}

export default {
    downloadUrl: downloadUrl,
    downFile: downFile
};

使用:

import axios from 'axios';
import downloadHelper from './DownloadHelper';

/*----------------------字节流文件下载-------------------------*/
/**
 * 获得文件数据并下载
 */
axios.get('http://crm.dev/api/v1/clients/exportExcel', {
    responseType: 'arraybuffer',
    headers: {
        'Accept': 'application/json',
        'Authorization': AUTH_TOKEN
    }
}).then(response => {
    var blob = new Blob([response.data], {type: 'application/vnd.ms-excel'});
    var fileName = '文件名称.csv';
    downloadHelper.downFile(blob, fileName);
});


/*-----------------------普通文件下载-------------------------*/
/**
 * 获取文件路径
 */
axios.get('http://crm.dev/api/v1/clients/excelTemplate', {
    headers: {
        'Accept': 'application/json',
        'Authorization': AUTH_TOKEN
    }
}).then(response => {
    downloadHelper.downloadUrl(response.data);
});