获取数据都知道,使用的是 axios,主要是设置 responseType: 'blob' 

由于项目使用的是 apipost ,所以在使用的时候还要设置 isReturnNativeResponse -是否返回本机响应标头,一般可能设置 responseType: 'blob'  就可以了

export function getDownZip(params?: object) {
  return defHttp.get(
    { url: Api.downZip, params: params, responseType: 'blob' },
    { isTransformResponse: false, isReturnNativeResponse: true },
  );
}

通过上面接口返回的数据就能直接使用下面方法下载

/**  
 * result.data 是对应的文件,具体的看返回数据,不一定存放在data中
 * 名称
 * 后缀名
 */
async function getData() {
 const result = await getDownZip({});
 downloadByData(result.data, '测试', 'application/json');
}

/** 
 * 根据后台接口文件流下载
 * @param {*} data
 * @param {*} filename
 * @param {*} mime
 * @param {*} bom
 */
export function downloadByData(data: BlobPart, filename: string, mime?: string, bom?: BlobPart) {
  const blobData = typeof bom !== 'undefined' ? [bom, data] : [data];
  const blob = new Blob(blobData, { type: mime || 'application/octet-stream' });

  const blobURL = window.URL.createObjectURL(blob);
  const tempLink = document.createElement('a');
  tempLink.style.display = 'none';
  tempLink.href = blobURL;
  tempLink.setAttribute('download', filename);
  if (typeof tempLink.download === 'undefined') {
    tempLink.setAttribute('target', '_blank');
  }
  document.body.appendChild(tempLink);
  tempLink.click();
  document.body.removeChild(tempLink);
  window.URL.revokeObjectURL(blobURL);
}

还可以通过 header中的content-disposition获取 fileName,成为文件的下载名称

可能会存在乱码问题,可以使用 decodeURIComponent 解决;

//从header中读取文件名称
const headerFilename = result.headers['content-disposition']?.split(';')[1].split('=')[1];

const fileName = decodeURIComponent(headerFilename);

downloadByData(result.data, fileName, 'application/json');

可能会在header中无法获取到 content-disposition ;

① 拦截时,只返回了部分数据,

// 添加响应拦截器
axios.interceptors.response.use(response=>{
    // 对响应数据做点什么
    return response.data; //这里只把这个响应里的data返回回来了,所以取不到headers,想要全部信息就return response;
  }, error=>{
    // 对响应错误做点什么
    return Promise.reject(error);
});

②后台没有返回 content-disposition 参数,需要后台搞一下;

查看了 network ,响应头确实有返回 content-disposition;但是打印以及通过.headers['content-disposition']就是获取不到;

 

是因为cros跨域,浏览器只会返回默认头部的header,并不能完全获取后端自定义的所有数据;

因此,需要后端在header中添加 Access-Control-Expose-Headers 信息;

响应首部 Access-Control-Expose-Headers 就是控制“暴露”的开关,它列出了哪些首部可以作为响应的一部分暴露给外部

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

这个时候就能在前端获取到响应的数据了 

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐