前端实现Blob下载功能(Content-Disposition问题与解决)
在Web应用中,我们经常需要实现文件的下载功能。有时,这个文件可能是用户上传的,有时则可能是服务器端生成的。不论哪种情况,我们都可以利用HTTP的
Content-Disposition
头信息来设定下载时的文件名。下面,我们就来看看如何在前端实现这个功能。
在实现这个功能时,前端需要通过调用接口,并通过接口请求头中的鉴权,获取到后端设置的
Content-Disposition
中的文件名,然后将数据流BloB化,下面分别使用xhr请求,fetch请求,axios请求进行代码示例实现下载功能。
一. 获取Content-Disposition问题与解决
在某些情况下,您可能无法直接从
HTTP
响应中获取
Content-Disposition
头,例如在使用Axios库时。默认情况下,只有六种简单响应头(
Simple Response Headers
)会暴露给外部:
Cache-Control, Content-Language, Content-Type, Expires, Last-Modified, Pragma
。
而Content-Disposition
并不在此列表中,因此即使服务器发送了该头,客户端也无法直接访问到它。
要解决这个问题,您需要在服务器端设置响应头
Access-Control-Expose-Headers
,将其值设置为允许暴露
Content-Disposition
头。这样,当您使用
Axios
库发起请求时,就可以在响应中访问到
Content-Disposition
头了。
二. 请求示例
1.使用xhr请求
使用原生
XMLHttpRequest
是实现这个功能的一种方式。下面是一段示例代码:
const xhr =newXMLHttpRequest();
xhr.open('get', url);
xhr.responseType ='Blob';
xhr.setRequestHeader('Authorization','token');// 权限验证,视情况修改
xhr.onreadystatechange=function(){if(this.readyState ===4&&this.status ===200){const name = fileName || xhr.getResponseHeader('Content-Disposition').split('filename=')[1];// 支持IE浏览器if(window.navigator && window.navigator.msSaveOrOpenBlob){
window.navigator.msSaveOrOpenBlob(this.response, name);return;}const href = window.URL.createObjectURL(this.response);const link = document.createElement('a');
link.style.display ='none';
link.href = href;
link.setAttribute('download', name);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);}};
xhr.send();
这段代码创建了一个新的
XMLHttpRequest
对象,然后打开一个到指定文件路径的连接,设置了
Content-Disposition
头信息,并发送了请求。
2.使用fetch请求
另一种方式是使用
fetch
API。这是一个更现代、更易用的网络请求方式。下面是一段示例代码:
const headers ={};
Object.assign(headers,{Authorization:`Bearer ${token}`});fetch('/path/to/your/file',{method:'GET',
headers
}).then(response=>{let name = response.headers.get('Content-Disposition').split('filename=')[1];
name =decodeURIComponent(name);// 创建一个a标签并设置href为blob的URL,然后模拟点击a标签实现下载功能const a = document.createElement('a');
a.href =URL.createObjectURL(response.blob());
a.download = name;// 后端设置的文件名
document.body.appendChild(a);
a.click();// 模拟点击a标签实现下载功能
document.body.removeChild(a);// 下载完毕后移除a标签}).catch(error=> console.error(error));
这段代码首先使用
fetch
API发起一个请求,然后在响应返回后,将数据流转化为一个Blob对象,接着创建一个新的a标签,设置其href为Blob对象的URL,并将文件名设置为后端设置的文件名,最后模拟点击a标签实现下载功能。
3.使用axios请求
最后,我们还可以使用
axios
库。这是一个基于Promise的HTTP库,可以用于浏览器和node.js。下面是一段示例代码:
axios({method:'get',url:'/path/to/your/file',responseType:'blob',fileName:'yourfilename.ext'// 后端设置的文件名}).then(response=>{const url =URL.createObjectURL(response.data);const a = document.createElement('a');
a.href = url;
a.download ='yourfilename.ext';// 后端设置的文件名
document.body.appendChild(a);
a.click();
document.body.removeChild(a);}).catch(error=> console.error(error));
版权归原作者 ts_shinian_web 所有, 如有侵权,请联系我们删除。