情况简介
后台
java开发的http 下载接口
1. 将文件内容写入 response.getOutputStream();
2. response.setContentType 设置文件类型
3. response.addHeader(“Content-Disposition”, “attachment;filename=文件名”)
前端 浏览器有3种下载方法
- window.open(url)
- form 表单post请求
- axios请求 + a标签
错误场景
docx文件大小6M
前端用的是a标签下载方法。用火狐浏览器,postman测试都成功
- 用谷歌浏览器下载时
- 请求状态200,
- 头信息返回正常
- body:failed to load reponse data
- 显示:下载失败-网络错误
先说结论
-
a标签下载有长度限制,不能超过浏览器URL长度限制(尤其是谷歌和ie,限制很小)
-
大文件下载用window.open(url)
解决方案原理汇总
- 高版本的chrome对字节流的下载进行了限制,需在头信息中声明字节流长度
- 解决方案
增加头信息Content-Length
- 解决方案
百度大多都是这个原因,可惜我的不是
- 前端用a标签下载,文件过大
a标签下载原理
a标签设置download 属性,下载url中的内容
- 原理步骤
- 用ajax发一次请求,收到返回body里的文件流
- 创建一个a标签, download = 自定义文件名, href = 文件流内容
- 点击a标签触发下载
<a href="url" download="filename"></a>
//发送http请求 返回res
send(params).then(res => {
if(res.data){ // res.data为后台返回的数据
//创建一个a标签
let a = document.createElement('a');
//解码,得文件名
const filename = decodeURI(res.headers['content-disposition'].split(';')[1]).replace('filename=','');
// a.download 指定下载的文件名
a.download = filename;
//指定文件MIME
let blob = new Blob([res.data],{type: "application/vnd.ms-excel"});
// a.href URL对象
a.href = URL.createObjectURL(blob);
// 模拟点击
a.click();
// 释放URL 对象
URL.revokeObjectURL(a.href);
}
浏览器下载规则(精华)
- 浏览器请求内容时,返回能展示就会直接展示(html,图片),
不能展示则 触发下载操作,弹出下载框 - 用Ajax请求,浏览器不会识别这是在进行下载操作,不会有弹出保存路径框。
- 各个浏览器对URL长度限制不同导致的;于是收集了各个浏览器的限制标准
IE 最大长度限制为2048字节
Chrome 最大长度限制为8182字节
Firefox 最大长度限制为65536字节
Safari 最大长度限制为80000字节
Opera 最大长度限制为190000字节