做外卖报表导出功能,前端使用fetch请求,后端在正常情况向会返回csv文件,在异常时会返回对应的异常码;前端的请求都是使用request.js做了统一拦截和错误提示,但是不支持文件下载,于是对原有内容稍作改造,支持文件下载。

前端是怎么实现文件下载的?

// 使用fetch发送请求并拿到返回值const response = await fetch(newUrl, responseBody);
// 将文件流转为blob对象,并获取本地文件链接response.blob().then((blob) => {const a = window.document.createElement('a');const downUrl = window.URL.createObjectURL(blob);// 获取 blob 本地文件连接 (blob 为纯二进制对象,不能够直接保存到磁盘上)const filename = response.headers.get('Content-Disposition').split('filename=')[1].split('.');a.href = downUrl;a.download = `${decodeURI(filename[0])}.${filename[1]}`;a.click();window.URL.revokeObjectURL(downUrl);});

实际场景中需要区分返回的是否是文件,文件走下载方法,数据走原有的request.js中定义的方法,这里需要使用响应头的Content-Type来判断,这里后端直返回CSV文件所以使用response.headers.get('Content-Type').indexOf('application/msexcel') > -1来判断是否为文件下载(响应头与后端约定好了)。

if (response.headers.get('Content-Type').indexOf('application/msexcel') > -1) {response.blob().then(执行文件下载)
} else {response.json();原有数据处理方法
}

request.js

import fetch from 'dva/fetch';
import { stringify } from 'qs';
import { message } from 'antd';
import { getFormData } from './index';/*** Requests a URL, returning a promise.** @param  {string} url       The URL we want to request* @param  {object} [options] The options we want to pass to "fetch"* @return {object}           An object containing either "data" or "err"*
/* message.config({top: 10,duration: 5,getContainer: () => window.document.getElementById('root'),
});*/
export default async function request(url, options) {let newOptions;let newUrl = url;let responseBody = {};let data = {};const { body, params } = options;// 判断请求类型if ((!(typeof body === 'string')) && body) {newOptions = Object.assign({}, options, { body: getFormData(body) });responseBody = {credentials: 'same-origin',...newOptions,};} else {newOptions = options;responseBody = {credentials: 'same-origin',headers: {'Content-Type': 'application/json',},...newOptions,};}// getif (params) {newUrl += `?${stringify(params)}`;}const response = await fetch(newUrl, responseBody);// 报表导出 Content-Type为application/msexcel时,为文件流,进行下载操作if (response.headers.get('Content-Type').indexOf('application/msexcel') > -1) {response.blob().then((blob) => {const a = window.document.createElement('a');const downUrl = window.URL.createObjectURL(blob);// 获取 blob 本地文件连接 (blob 为纯二进制对象,不能够直接保存到磁盘上)const filename = response.headers.get('Content-Disposition').split('filename=')[1].split('.');a.href = downUrl;a.download = `${decodeURI(filename[0])}.${filename[1]}`;a.click();window.URL.revokeObjectURL(downUrl);});return data;}if (response.status !== 200) {message.error('网络或服务器异常!');return {data: {code: response.status,},};}data = await response.json();if (data.code !== '200') {// 状态码不为304或302的时候报错if (data.code !== '304' && data.code !== '302') {console.log(data.msg);message.error(data.msg);}// 状态码为304的时候,请求登录接口if (data.code === '304') {request('/login', {method: 'post',body: {...data.data,redirect_uri: encodeURIComponent(window.location.href),},});}// 状态码为302的时候,进行跳转if (data.code === '302') {window.location = data.msg;}}return { data };
}

fetch下载文件--统一拦截导出文件相关推荐

  1. 如何使用IDM分类管理下载文件

    IDM作为一款强大的下载器,能够无缝集成到主流浏览器中捕获数据源,支持代理服务器,下载性能稳定快速.高速下载带给用户更多的高效体验的同时,也带来了很多不同的数据文件,时间积累就会杂乱无章. 可能很多I ...

  2. [html] 通过设置表单的target=“_blank“来下载文件会被浏览器拦截吗?如何解决?

    [html] 通过设置表单的target="_blank"来下载文件会被浏览器拦截吗?如何解决? 不用表单下载,动态创建一个a标签, 设置href, target="_s ...

  3. flutter网络请求dio的get、post、上传文件、下载文件总结

    题记 -- 执剑天涯,从你的点滴积累开始,所及之处,必精益求精,即是折腾每一天. 重要消息 flutter中网络请求dio使用分析 视频教程在这里 Flutter 从入门实践到开发一个APP之UI基础 ...

  4. new blob文件设置编码_前端下载文件amp;下载进度

    前端最基础的就是 HTML+CSS+Javascript.掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些.前端小课堂(HTML/CSS/JS),本着提升技术水平,打牢基础 ...

  5. a标签下载文件header中带上用于鉴权的token

    加了统一鉴权以后  如果把下载接口也拦截了 且前端使用的是a标签 可以用如下方法解决 替换调请求url和请求方式 , 方式一和方式二任意注释一个就可以运行了 方式1用的是原生的XmlHttpReque ...

  6. A 标签下载文件 Header 中带上用于鉴权的 Token

    加了统一鉴权以后,可能会把 A 标签下载的接口也给拦截了,但是 A 标签是无法带上 Token 的,本文将介绍如何让 A 标签支持像 Ajax 一样发送请求. 加了统一鉴权以后 如果把下载接口也拦截了 ...

  7. js下载文件、音频、视频的方式

    下载文件可以直接通过a标签的href属性直接下载,也可以通过Blob对象转换为文件流进行下载.如果要对大数据量或者需要分片下载.上传等操作,可以考虑Blob对象.同事Blob对象可以对下载过程进行额外 ...

  8. 爬虫框架Scrapy(10)下载文件与图片

    文章目录 下载文件与图片 (一)FilesPipeline 和 ImagesPipeline 1. FilesPipeline 使用说明 2. ImagesPipeline 使用说明 (二)项目实例: ...

  9. 微信无法下载文件做提示跳转到浏览器

    问题分析 当我们在微信内分享链接或二维码的时候,我们会发现我们的网站是可以在浏览器里正常打开的,但就是不能在微信里打开,提示 " 已停止访问该网页 ",无论是聊天框也一样.说是系统 ...

最新文章

  1. 算法导论一个让人很不爽的地方
  2. 5月22日云栖精选夜读:PHP学习路线图
  3. C++shell sort希尔排序的实现算法之一(附完整源码)
  4. mysql部署jar_mysql+jar踩坑记录
  5. Java 数据类型和 MySql 数据类型对应一览表
  6. jquery-validation 使用
  7. SpringMVC的RESTful(一)
  8. 论文笔记_S2D.57_2018-IROS_LIMO:激光雷达单目视觉里程计
  9. 用python做股票因子分析_因子分析(by+alphalens)
  10. 彻底解决chrome等浏览器被劫持(篡改主页hao123等)问题
  11. SAP官方培训课程级别和PA认证介绍
  12. php fpm在哪配置,php配置php-fpm启动参数及配置详解
  13. 如何用C语言编程序化交易,程序化交易的开发步骤
  14. 大学及毕业总共9年时间追求过一个女孩却最终没有成功,期间的心酸,痛苦,怨恨以及最后消散写成了这篇2万字的散文诗小说。每一个字都是自己的心血,试问人生有几个9年?更何况是在你最美好的年华。喜欢的交流下。
  15. 2021年中国开源优秀人物揭晓
  16. python常用处理脚本
  17. (附源码)springboot 新闻管理系统 毕业设计 211113
  18. 关于深度学习,可能是最容易读进去的科普
  19. 并行编程1——什么是并行程序?
  20. 北大ACM线上比赛有感

热门文章

  1. 半路出家当程序员容易吗?怎样才能拿高薪?
  2. stm32f407+lwip+freertos程序
  3. 第八章:拆解VCM音圈马达,原理、结构
  4. 46家公司面试笔试题
  5. 微信小程序架构分析 (下)
  6. Java实现多线程聊天室
  7. 移动终端网页游戏移植研发框架【精灵系统-纸娃娃】
  8. java做主成分分析_主成分分析PCA
  9. 云原生时代,paas,apaas,ipaas,bpaas,baas,daas是什么
  10. 蚂蚁分类信息系统增加游客发布信息需要手机验证码选项