js下载文件的实现方式
供参考,平时遇到的问题记录一、普通下载
当后端返回的资源是链接时,此时可以使用
a
标签或者 window.location.href
直接打开。1、a 标签形式 在H5中,
a
标签新增了download
属性,包含该属性的链接被点击时,浏览器会以下载文件方式下载 href 属性上的链接。 下载// 或者封装
function download(href, title) {
const a = document.createElement('a');
a.setAttribute('href', href);
a.setAttribute('download', title);
a.click();
}
download('https://example.com', 'test')
2、window.location.href 直接打开
window.location.href =https://www.it610.com/article/=='https://example.com'
二、流文件下载
当后端返回的文件是流文件时,以
umi-request
请求方法为例首先应在请求中设置返回类型:
responseType: "blob"
import request from "umi-request";
export const downLoad = (url, fileName) =>
request(url, {
method: "POST",
data: data,
responseType: "blob", // 代表内存之中的一段为二进制
}).then(data) => {
const blob = data;
let link = document.createElement("a");
link.href = https://www.it610.com/article/URL.createObjectURL( new Blob([blob], { type:"application/vnd.ms-excel" }) );
link.download = fileName;
document.body.appendChild(link);
link.click();
URL.revokeObjectURL(link.href);
};
1、自定义文件名 此时可以发现后端返回的是流文件,前端接到的是乱码。当前端自定义文件名时,可以直接下载
downLoad('https://example.com/api/download', 'test.xlsx')
2、采用后端定义的文件名 当采用后端的
fileName
时,此时要获取后端在 content-disposition
中定义的文件名。首先调用接口,发现文件名是在请求头
content-disposition
中,需要注意的是:虽然我们能看到,但是却拿不到请求头。如果想让浏览器能访问到其他响应头的话,需要后端在服务器上设置
Access-Control-Expose-Headers
// 后端面大致写法
headers.add("Access-Control-Expose-Headers", "Content-Disposition");
此时可以拿到相关信息,发现是编码的,需要decodeURI 进行解码
const disposition = response.headers.get('Content-Disposition');
const fileName = decodeURI(disposition.split(";
")[1].split("filename=")[1])
注:直接在请求方法里是不能获取到请求头信息的,需要对请求进行拦截
request.interceptors.response.use(async (response) => {
const disposition = response.headers.get("Content-Disposition");
// 获取Content-Disposition
return disposition // 当Content-Disposition中有值的时候进行处理,其他请求的响应则放过
? {
blob: await response.blob(), // 将二进制的数据转为blob对象,这一步是异步的因此使用async/await
fileName: decodeURI(disposition.split(";
")[1].split("filename=")[1]), // 处理Content-Disposition,获取header中的文件名
}
: response;
});
完整的代码如下: request 文件
import request from "umi-request";
// 响应拦截
request.interceptors.response.use(async (response) => {
const disposition = response.headers.get("Content-Disposition");
// 获取Content-Disposition
return disposition // 当Content-Disposition中有值的时候进行处理,其他请求的响应则放过
? {
blob: await response.blob(), // 将二进制的数据转为blob对象,这一步是异步的因此使用async/await
fileName: decodeURI(disposition.split(";
")[1].split("filename=")[1]), // 处理Content-Disposition,获取header中的文件名
}
: response;
});
export const downLoadExcel = (url) =>
request(url, {
method: "POST",
data: data,
// responseType: "blob", // 注释掉这一段
}).then(data => {
const { blob, fileName } = response;
let link = document.createElement("a");
link.href = https://www.it610.com/article/URL.createObjectURL( new Blob([blob], { type:"application/vnd.ms-excel" }) );
link.download = fileName;
document.body.appendChild(link);
link.click();
URL.revokeObjectURL(link.href);
document.body.removeChild(link);
});
react 文件
下载
【js下载文件的实现方式】js 文件
async download() {
await downLoadExcel('http://example.com/api/download');
},
推荐阅读
- 热闹中的孤独
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 放屁有这三个特征的,请注意啦!这说明你的身体毒素太多
- 一个人的旅行,三亚
- 布丽吉特,人生绝对的赢家
- 慢慢的美丽
- 尽力
- 一个小故事,我的思考。
- 家乡的那条小河
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量