前言:前段时间后端给了一个 post 下载文件得接口,当时就脑子一蒙蔽,什么情况为什么不是直接通过 url 得形式下载文件,特此写下了这一篇思考。
post 下载文件是否可行
答案时肯定可行得
responseType 设置为 blob 得时候能够做到 response 为Blob 数据
const url = URL.createObjectURL(new Blob([response.data] ));
const downloadElement = document.createElement("a"); downloadElement.href = url;
downloadElement.download = "download_file_name";
document.body.appendChild(downloadElement);
downloadElement.click();
document.body.removeChild(downloadElement);
window.URL.revokeObjectURL(url);
post 下载文件得问题在哪里
我总结了已下几点
- 响应时间过长
- 下载文件没有进度条
- responseType 固定为 blob 不能同时支持 json
- 处理复杂
响应时间过长
响应时间会直接和响应能容挂钩,一般文件越大处理响应越长。如果接口频率过高,后端直接读取文件响应,那么处理io 也会更加夸张,会有堵塞现象产生。
下载文件没有进度条
因为异步请求不同于浏览器默认下载处理,那么在要在显示下载进度得时候也就比较困难了。(可以通过 onprogress 来做到进度控制)
responseType 固定为 blob 不能同时支持 json
不好处理复杂业务场景,因为请求响应得时候必须得设置 responseType 为 blob 那么在业务处理错误得时候对于 处理错误行为就不好处理了。因为后端此时返回得是 json 你必须得通过 FileReader 达到
const reader = new FileReader();
reader.onload = (e: any) => {
if (e.target.readyState === 2) {
const res = JSON.parse(e.target.result);
// result json
}
};
reader.readAsText(response.data);
处理复杂
说了这么多还是想说,通过 post 下载文件前端实现太过复杂而且响应时长不能很好控制。
怎么解决 post 下载文件呢
- 把原本得post 请求下载文件改为 post请求下载地址
- open url 既可以达到
流程简单,但是也有特殊情况 文件下载地址不好做权限管理。会有数据泄露风险。
那么我们是不是可以在url 地址上做一些特殊得安全处理,例如url 过期失效。或者url携带临时下载令牌之类得。