使用xhr实现后台返回 Content-Type: application/octet-stream 流的下载

import _ from 'lodash';

import Env from '@/utils/environment';

import moment from 'moment';

import { DATETIME_FORMAT } from '@/utils/format';

import Token from '@/utils/common-data/token';

export default (

  data,

  options = {

    setFileName: () => `${moment().format(DATETIME_FORMAT)}.zip`,

    requestConfig: {

      headers: {}

    }

  }

) =>

  new Promise((resolve, reject) => {

    const token = _.get(Token.vuexToken, 'token', '');

    const request = new XMLHttpRequest();

    request.open('post', Env.backendSearchApiBaseUrl + '/v1/export', true);

    request.setRequestHeader('Content-Type', 'application/json');

    request.setRequestHeader('Authorization', token);

    request.responseType = 'blob';

    request.timeout = options.timeout ? options.timeout : 30000;

    const { setFileName, requestConfig } = options;

    const { headers, ...res } = requestConfig;

    Object.keys(headers).forEach(key => {

      request.setRequestHeader(key, headers[key]);

    });

    Object.keys(res).forEach(key => {

      request[key] = res[key];

    });

    request.onloadend = function() {

      if (request.readyState == 4) {

        if (request.status === 200) {

          const content = request.response;

          const blob = new Blob([content]);

          const fileName = _.isFunction(setFileName)

            ? setFileName()

            : _.isString(setFileName)

            ? setFileName

            : `${moment().format(DATETIME_FORMAT)}.zip`;

          if ('download' in document.createElement('a')) {

            // 非IE下载

            const elink = document.createElement('a');

            elink.download = fileName;

            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);

          }

          resolve({ ok: true });

        } else {

          reject({ ok: false, errorType: 'result_error', message: '导出失败' });

        }

      }

    };

    request.ontimeout = function() {

      reject({

        ok: false,

        errorType: 'timeout_error',

        message: '请求超时'

      });

    };

    request.onerror = function() {

      reject({

        ok: false,

        errorType: 'onerror',

        message: '导出出错'

      });

    };

    request.send(JSON.stringify(data));

  });

你可能感兴趣的:(使用xhr实现后台返回 Content-Type: application/octet-stream 流的下载)