文件下载的解决方案探索

背景

再现在正在进行的项目中,由于后端涉及到网关安全控制(我也不是太懂,毕竟不是专业),我的后端搭档没有找到好的提供静态文件服务的方式,只好以流的方式向前端写入,在前端进行如下操作:

  1. 前端接收blob
  2. 使用URL.createObjectURL() 或者 FileReader 创建下载url
  3. 使用a标签 href, download click() 来进行下载

但是这种方式是有缺点的

  • 对于开发者来说,需要配合xhr方法来编写,增加代码量
  • 只有拿到所有的二进制字节数才能进行转化url,在浏览器上才有可能看见文件已被下载
  • 不支持断点续传,只能重新进行下载

对于小文件这种方式其实没有影响, 因为时间会很短,对于很大的文件来说这种方式就不可接受了,因为接收二进制字节的时间是不可控的,如果非常大的文件,在接收二进制的过程中,页面是完全无反馈的,这对于用户体验是不可接受的

流方式的文件下载

另外一套方案就是,在后端以方法文件流的方式向前端输出文件也是可以直接下载的
原理就是设置请求头

  1. res.setHeader(‘Content-Type’, ‘application/zip’) // 设置下载文件的mime类型
  2. res.setHeader(‘Content-Length’, 38282773) // 这个对于小文件可以不进行设置,不影响下载,对于大文件一定要设置文件大小,否则有可能下载坏的文件
  3. res.setHeader(‘Content-Disposition’, “attachment; filename=1.zip”) 在常规的 HTTP 应答中,Content-Disposition 响应头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地。

以node.js为例

	const path = require('path')
	const fs = require('fs')
	const http = require('http')
	
	
	const server = http.createServer((req, res) => {
	    console.log('请求来了')
	    res.setHeader('Content-Type', 'application/zip')
	    res.setHeader('Content-Length', 38282773)
	    res.setHeader('Content-Disposition', "attachment; filename=1.zip")
	    fs.createReadStream(path.resolve('1.![在这里插入图片描述](https://img-blog.csdnimg.cn/20210624004007725.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NoZW5wYXBh,size_16,color_FFFFFF,t_70)
zip')).pipe(res)
	})
	
	server.listen(3000)

文件会被直接下载,会在浏览器上显示进度条,用户的反馈问题便被解决了,断点续传也解决了,如果安装了迅雷等下载软件,会被拉取到迅雷中进行下载。

chrome
在这里插入图片描述
在这里插入图片描述

edge
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值