axios文件下载的各种方法

axios

查看源码发现axios返回的内容默认是Stream格式的;

如果没有设置responseType的话,返回内容将会从Stream转为Buffer再转为String;

如果responseType为stream的话不进行转换;

如果responseType为arraybuffer的话将Stream转为Buffer;

但是如果想把Buffer转为String再转回Buffer的话将会出问题(默认使用utf8进行Buffer的编码和解码),有的文件这样是可以的,但是Excel文件这样做的话两次Buffer的值是不同的;但是转为base64的话是都可以的。

方法一:设置responseType为stream

const result = await require('axios')({ url, method, data, responseType: 'stream' });
result.data.pipe(require('fs').createWriteStream(saveFilePath));

提供buffer转Stream并保存为文件的方法

function bufferToStream(bufferData, saveFilePath) {
  return new Promise((res, rej) => {
    const bufferStream = new stream.PassThrough();
    bufferStream.end(bufferData);
    const ws = fs.createWriteStream(saveFilePath);
    bufferStream.pipe(ws).on('finish', () => {
      res(saveFilePath);
    });
  });
}

方法二:设置responseType为arraybuffer

const result = await require('axios')({ url, method, data, responseType: 'arraybuffer' });
const bufferData = result.data;
await bufferToStream(bufferData, saveFilePath);

方法三:不设置responseType,设置responseEncoding为base64

const result = await require('axios')({ url, method, data, responseEncoding: 'base64' });
const bufferData = Buffer.from(result.data, 'base64');
await bufferToStream(bufferData, saveFilePath);

附上axios相关源码

/adapters/http.js


var req = transport.request(options, function handleResponse(res) {
  if (req.aborted) return;

  // uncompress the response body transparently if required
  var stream = res;
  switch (res.headers['content-encoding']) {
  /*eslint default-case:0*/
  case 'gzip':
  case 'compress':
  case 'deflate':
    // add the unzipper to the body stream processing pipeline
    stream = (res.statusCode === 204) ? stream : stream.pipe(zlib.createUnzip());

    // remove the content-encoding in order to not confuse downstream operations
    delete res.headers['content-encoding'];
    break;
  }

  // return the last request in case of redirects
  var lastRequest = res.req || req;

  var response = {
    status: res.statusCode,
    statusText: res.statusMessage,
    headers: res.headers,
    config: config,
    request: lastRequest
  };
  if (config.responseType === 'stream') {
    response.data = stream;
    settle(resolve, reject, response);
  } else {
    var responseBuffer = [];
    stream.on('data', function handleStreamData(chunk) {
      responseBuffer.push(chunk);

      // make sure the content length is not over the maxContentLength if specified
      if (config.maxContentLength > -1 && Buffer.concat(responseBuffer).length > config.maxContentLength) {
        stream.destroy();
        reject(createError('maxContentLength size of ' + config.maxContentLength + ' exceeded',
          config, null, lastRequest));
      }
    });

    stream.on('error', function handleStreamError(err) {
      if (req.aborted) return;
      reject(enhanceError(err, config, null, lastRequest));
    });

    stream.on('end', function handleStreamEnd() {
      var responseData = Buffer.concat(responseBuffer);
      if (config.responseType !== 'arraybuffer') {
        responseData = responseData.toString(config.responseEncoding);
      }
      response.data = responseData;
      settle(resolve, reject, response);
    });
  }
});

你可能感兴趣的:(js,eggjs,node.js,javascript)