文章目录
- 前言
-
- 一、a标签 + download属性
- 二、window.open(url, "_blank")
- 三、form表单
- 四、接口请求 + blob + a标签+ download属性
- 下载涉及的HTTP协议 header字段
前言
前端业务开发中,经常会遇到下载图片、文件等需求。前端需要拿到二进制流才能进行下载操作。
二进制流
在前后端交互中,二进制流可能是一个文件或者图片以流的形式传递。
前端核心实现下载功能有:
<a href="xxx" downlaod="filname"></a>
window.open()
form
表单提交ajax
请求接口,处理文件流转为blob
格式
在实际业务中,根据实际接口和URL具体情况,制定具体的实现方案
一、a标签 + download属性
适用场景:
- fileUrl是【同源】的
- Get请求
- 不能设置请求头,不能携带token等验证身份信息
非适用异常场景:
- 对于非同源URL,比如协议不一致,例如当前访问页面协议是https,而fileUrl是http协议地址,浏览器会拦截下载请求(在fileUrl同时支持http和https协议时,前端也可转换一下fileUrl协议)。
- 对于非同源URL,协议一致,但是比如第三方链接:腾讯云图片链接,即使设置了download属性,在某些浏览器异常表现是:下载文件的同时会自动变更当前访问地址。
const a = document.createElement("a");
document.body.appendChild(a);
a.setAttribute("style", "display:none");
a.setAttribute("href", fileUrl);
a.setAttribute("download", fileName);
a.click();
URL.revokeObjectURL(fileUrl);
二、window.open(url, “_blank”)
原理和a标签类似,也是适用于Get请求
三、form表单
使用场景:
- POST\GET请求
- 需要携带较多参数
- 可以设置请求头,携带token等验证信息
const downLoadForm = ({ formData, url }) => {
let formStr = `<form action="${url}" method="post" id="sendAll" target="_self">`;
for (let k in formData) {
formStr += `<input type="hidden" value="${formData[k]}" name="${k}" />`
}
formStr += `</form>`;
const body = document.querySelector('body');
const container = document.createElement('div');
container.innerHTML = formStr;
body.append(container);
document.querySelector('#sendAll').submit();
container.remove();
}
四、接口请求 + blob + a标签+ download属性
适用场景:
- POST\GET请求
- 要下载第三方(腾讯云)图片地址,可以让后端提供统一的下载接口,拿到文件流,前端通过blob接收解析,再用a标签下载
- 可以设置请求头,携带token等验证用户信息
export const downloadImg = (params) => {
return axios.post(api.downloadImg, null, { params, responseType: 'blob' });
}
downloadImg({url}).then(data => {
const blob = new Blob([data], {type: data.type});
const objectUrl = URL.createObjectURL(blob);
const a = document.createElement("a");
document.body.appendChild(a);
a.setAttribute("style", "display:none");
a.setAttribute("href", objectUrl);
a.setAttribute("download", fileName);
a.click();
URL.revokeObjectURL(objectUrl);
}).catch(err => {
console.log('err', err)
})
下载涉及的HTTP协议 header字段
- Content-Type (实体头部用于指示资源的MIME类型 media type )
具体查看:不同类型对应的media type
Content-Type: application/octet-stream
- Content-Length (用来指明发送给接收方的消息主体的大小,即用十进制数字表示的八位元组的数目。)
- Content-Disposition( 响应头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地。)
Content-Disposition: attachment;filename=test.xlsx;filename*=UTF-8
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)