概要

前端上传文件的例子很多, 但是下载相关的例子不多, 主要是因为下载本身比较简单.

但是这次做了个文件导出功能, 接收文件流的时候弄了很长时间也没有成功, 就因为请求中缺了个配置…

示例

后端

后端比较简单, 不管有多少需要计算的业务, 最终只是返回文件流.

下面的示例是通过 golang gin 框架实现的.

 1  package main
2
3 import (
4 "strconv"
5
6 "github.com/gin-gonic/gin"
7 )
8
9 func main() {
10 route(8000)
11 }
12
13 func route(port int) error {
14
15 r := gin.Default()
16 apiV1 := r.Group("/api/v1")
17
18 // file download
19 apiV1.GET("/download/:fileName", DownloadFile)
20
21 return r.Run(":" + strconv.Itoa(port))
22 }
23
24 func DownloadFile(c *gin.Context) {
25 fileName := c.Param("fileName")
26
27 c.File("./download/" + fileName)
28 }

根据 url 中的文件名, 直接返回 download 文件夹下的某个文件

前端

前端一般有以下几种情况的下载:

直接显示图片

直接将文件流赋给 img 的 src 就行

1  <img src={"http://localhost:8000/api/v1/download/test.png"} width={50} height={60} />

提供下载链接, 点击后下载

1  <a href={"http://localhost:8000/api/v1/download/test.pdf"} />

文件导出, 前端没有显示下载链接的位置

这种方式需要前端模拟一个 a 标签的点击, 从而实现文件的下载.

 1  export async function exportFile(params) {
2 return postJson('/api/v1/download/test.xlsx, params, 'blob').then((res) => {
3 let url = URL.createObjectURL(new Blob([res]));
4 let filename = '导出记录.xlsx';
5 let a = document.createElement('a');
6 a.href = url;
7 a.download = filename;
8 a.click();
9 URL.revokeObjectURL(url);
10 });
11 }
12
13 const postJson = async (url, params, responseType = '') {
14 const response = await request(url, {
15 method: 'POST',
16 header: {
17 'Content-Type': 'application/json',
18 },
19 data: params,
20 responseType: responseType,
21 });
22
23 // 省略... (对response的一些处理)
24
25 return Promise.resolve(response);
26 }

这里有个关键的配置 responseType: 'blob' 这个配置不在 header 中,

和 header, data 是平级的. (当时就是这个配置导致导出功能卡了半天, 如果没有这个配置, 导出之后会显示文件已经损坏)

最新文章

  1. 自己总结SVN必知点
  2. asp.net关于如何准许api跨域访问
  3. QQ邮箱发送邮件,出现mail from address must be same as authorization user错误
  4. Hive 一些便捷小查询
  5. 什么是AIDL(转)
  6. Android 禁用以及捕捉home键
  7. Python标准库03 路径与文件 (os.path包, glob包)
  8. Makefile 多目录自动编译
  9. 12_RHEL7.1普通用户添加sudo权限
  10. cursor:pointer 什么意思?
  11. ECJTUACM16 Winter vacation training #5 题解&amp;源码
  12. Python的魔法函数系列 __getattrbute__和__getattr__
  13. echarts 修改y轴刻度间隔问题
  14. Javaweb学习笔记——(十三)——————JSTL、JSTL核心标签库、自定义标签、有标签体的标签、带有属性的标签、MVC、Javaweb三层框架
  15. cocos2dx 3.13 在Mac平台下配置安卓环境变量
  16. TypeScript 之 tsconfig.json
  17. PHP取整,四舍五入取整、向上取整、向下取整、小数截取
  18. 使用office打印到文件功能进行打印测试
  19. 即时通讯之smack客户端配置
  20. [USACO11DEC]Umbrellas for Cows

热门文章

  1. 保存vuex状态刷新不消失
  2. IE9 报错 script1004缺少“;”
  3. Nginx升级加固SSL/TLS协议信息泄露漏洞(CVE-2016-2183)
  4. 关于HTML基本标签,了解一下!
  5. 真正的解决IDEA中Tomcat控制台乱码的问题
  6. [LeetCode]105. 从前序与中序遍历序列构造二叉树(递归)、108. 将有序数组转换为二叉搜索树(递归、二分)
  7. 【LeetCode/LintCode】丨Google面试题:N皇后问题
  8. Windows Server系统部署MySQL数据库
  9. Raspberry Pi 4B 安装 CentOS 8
  10. 记一次&quot;截图&quot;功能的项目调研过程!