axios请求api然后下载文件
# axios请求api然后下载文件
首先我们需要把axios实例建立好,在这一步,你可以把接口需要的token等内容加入进去
const instance = axios.create({
headers: {
'jwt-token': Auth.getJwtToken()
},
responseType: 'blob'
});
1
2
3
4
5
6
2
3
4
5
6
然后我们发起请求,这时候我们可以让页面进入加载状态,然后不管怎么样,我们需要结束加载
startLoading();
const res = await instance.request({url, method, params, data}).finally(endLoading);
1
2
2
然后开始处理接口返回的内容
如果后端报错,这里会返回JSON格式的文件,需要我们自己取处理
这里的errorFunc是调用者传进来的,这样方便调用者更好的显示错误
最后我们只需要把取到的Blob下载下来,我们可以随便搜到一个downloadBlob函数
if (!filename) {
const contentDisposition = res.headers['content-disposition'];
filename = contentDisposition ? decodeURIComponent(contentDisposition.split('filename=')[1]) : '文件';
}
const contentType = (res.headers['content-type'] && res.headers['content-type'].split(';')[0]) ||
'application/octet-stream';
if (res.data instanceof Blob) {
if (res.data.type === 'application/json') { // 处理后端报错的情况
const rawText = await res.data.text();
const raw = JSON.parse(rawText);
if (raw.code && raw.code !== 0) {
console.warn(raw.message);
errorFunc && typeof errorFunc === 'function' && errorFunc(raw.message);
}
} else {
downloadBlob(res.data, filename);
}
} else {
const blob = new Blob([res.data], {
type: contentType
});
downloadBlob(blob, filename);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
接下来是完整的代码
const getFile = async ({url, method = 'get', params = {}, data = {}, errorFunc, filename}) => {
const instance = axios.create({
headers: {
'jwt-token': Auth.getJwtToken()
},
responseType: 'blob'
});
startLoading();
const res = await instance.request({url, method, params, data}).finally(endLoading);
if (!filename) {
const contentDisposition = res.headers['content-disposition'];
filename = contentDisposition ? decodeURIComponent(contentDisposition.split('filename=')[1]) : '文件';
}
const contentType = (res.headers['content-type'] && res.headers['content-type'].split(';')[0]) ||
'application/octet-stream';
if (res.data instanceof Blob) {
if (res.data.type === 'application/json') { // 处理后端报错的情况
const rawText = await res.data.text();
const raw = JSON.parse(rawText);
if (raw.code && raw.code !== 0) {
console.warn(raw.message);
errorFunc && typeof errorFunc === 'function' && errorFunc(raw.message);
}
} else {
downloadBlob(res.data, filename);
}
} else {
const blob = new Blob([res.data], {
type: contentType
});
downloadBlob(blob, filename);
}
};
const downloadBlob = (blob, filename) => {
if (typeof window.navigator.msSaveBlob !== 'undefined') {
// IE doesn't allow using a blob object directly as link href.
// Workaround for "HTML7007: One or more blob URLs were
// revoked by closing the blob for which they were created.
// These URLs will no longer resolve as the data backing
// the URL has been freed."
window.navigator.msSaveBlob(blob, filename);
return;
}
// Other browsers
// Create a link pointing to the ObjectURL containing the blob
const blobURL = window.URL.createObjectURL(blob);
const tempLink = document.createElement('a');
tempLink.style.display = 'none';
tempLink.href = blobURL;
tempLink.setAttribute('download', filename);
// Safari thinks _blank anchor are pop ups. We only want to set _blank
// target if the browser does not support the HTML5 download attribute.
// This allows you to download files in desktop safari if pop up blocking
// is enabled.
if (typeof tempLink.download === 'undefined') {
tempLink.setAttribute('target', '_blank');
}
document.body.appendChild(tempLink);
tempLink.click();
document.body.removeChild(tempLink);
setTimeout(() => {
// For Firefox it is necessary to delay revoking the ObjectURL
window.URL.revokeObjectURL(blobURL);
}, 100);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
上次更新: 2023/06/01, 12:40:50