最近工作中遇到的一些小坑

142 阅读1分钟

我正在参加掘金「掘金·启航计划」。

前端excel导出

​ 最近的项目中有一个小功能,后端返回一个文件流,前端把excel保存在本地即可。当时想着是一个很简单的事情,只需要生成一个 a 链接,把文件流转换一下二进制,把 a 标签的 href 属性指向这个二进制就可以了。

 const blob = new Blob([res], {
   type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8" });
 let link = document.createElement("a");
 link.style.display = "none";
 link.href = URL.createObjectURL(blob);
 link.setAttribute("download", "指标对比.xlsx"); // 制定下载文件名
 document.body.appendChild(link);
 link.click();
 document.body.removeChild(link); //下载完成移除元素
 window.URL.revokeObjectURL(link.href); //释放掉blob对象

tips: type要跟后端返回的文件流类型一样

当时代码这样写的完全没有问题,结果用起来就是报错,报接口异常。当时百度,问同事。都说没问题,卒子后我一看报错的地方。是响应拦截器报的错。这个项目返回的数据格式必须要有deta,code。结果文件导出的接口只有一个文件流。导致响应拦截报错。

解决办法就是重新创建一个 axios 实例,不走响应拦截器。

/**
 * @description: 纯净请求post处理文件流
 * @param {string} url
 * @param {object} params
 * @param {object} options
 * @return {*}
 */
export const purePost = (url: string, params: object, options: { [key: string]: any } = {}) => {
  return pureRequest({
    url: url,
    method: 'post',
    data: params,
    responseType: 'arraybuffer',
    headers: {
      'x-token': getCookie('x-token'), // 向后台发送的token
      'x-no-encrypt': true,
      'Content-Type': 'application/json;charset=utf-8',
      ...options,
    },
  });
}

这里也有一个小坑,封装请求的时候要添加一个 responseType属性,不加会导致文件导出无法打开的情况。

tips: post请求为arraybuffer,get请求为blob

最后前端导出文件流就搞定了。水一篇文章,拿一点奖励!☺