1 案例
通过 fetch 发起请求获取文件,再用 Blob 对象来接收处理。接收到后端返回的文件后,将其放入 a 标签 的 href,并触发下载行为。实现的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| const formData = new FormData(); formData.append("msg", "download");
fetch(url, { method: "POST", body: formData, headers: new Headers({ "Content-Type": "application/json;charset=UTF-8" }), }) .then((response) => { return response.blob(); }) .then((blob) => { const link = document.createElement("a"); link.style.display = "none"; link.href = URL.createObjectURL(blob); document.body.appendChild(link); link.click(); URL.revokeObjectURL(link.href); document.body.removeChild(link); });
|
注意:调用 response 的 blob 方法会返回一个 promise 对象
2 处理文件名
上一个步骤下载得到的文件名是无意义的。假设服务端把文件名放在 content-disposition
头:
1 2 3 4 5
| response.setContentType("application/octet-stream"); response.setHeader("Access-Control-Expose-Headers", "Content-disposition"); response.setHeader("Content-disposition", "attachment;filename=" + fileName); response.flushBuffer(); workbook.write(response.getOutputStream());
|
前端可采用 split 方法提取。完整实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| fetch(url, { method: "POST", body: formData, headers: new Headers({ "Content-Type": "application/json;charset=UTF-8" }), }).then(function (response) { const filename = res.headers .get("content-disposition") .split(";")[1] .split("=")[1];
response.blob().then((blob) => { const link = document.createElement("a"); link.style.display = "none"; link.download = filename; link.href = URL.createObjectURL(blob); document.body.appendChild(link); link.click(); URL.revokeObjectURL(link.href); document.body.removeChild(link); }); });
|
注:a 标签的 download 属性就是文件名
或者用 async/await
实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| async function download(url) { const request = { method: 'POST', body: formData, headers: new Headers({ "Content-Type": "application/json;charset=UTF-8" }), }
const response = await fetch(url, request) const filename = response.headers.get('content-disposition').split(';')[1].split('=')[1] const blob = await response.blob()
const link = document.createElement('a') link.download = decodeURIComponent(filename) link.style.display = 'none' link.href = URL.createObjectURL(blob) document.body.appendChild(link) link.click() URL.revokeObjectURL(link.href) document.body.removeChild(link)j }
|