axios post 请求中下载文件流
前端一般下载文件都是 window.open(url)
下载, 但有时候后端返回的是文件流, 就不能使用这种方式下载了
下面看一下下载文件流注意事项:
1、首先确保后端的是输出流格式 2、axios 的服务器响应的数据类型为 responseType:blob 3、返回的数据流占用 response.data 字段
# 简单使用
// NodeJS
var express = require('express')
var app = express()
app.post('/download', function(req, res, next) {
res.setHeader('Content-Type', 'application/vnd.ms-excel')
res.write('123456')
res.end()
})
1
2
3
4
5
6
7
2
3
4
5
6
7
// WEB 端代码:
axios({
method: 'post', // 请求方式
url: 'http://localhost:3000/download',
data: {
id: 1
}, // 请求参数
responseType: 'blob' // 服务器返回的数据类型
}).then(response => {
const content = response.data // 返回的内容
const fileName = '文件.xls' // 下载文件名
download(content, fileName)
})
//处理下载流
function download(content, fileName) {
const blob = new Blob([content]) // 创建一个类文件对象:Blob 对象表示一个不可变的、原始数据的类文件对象
const url = window.URL.createObjectURL(blob) // URL.createObjectURL(object) 表示生成一个 File 对象或 Blob 对象
let dom = document.createElement('a') // 设置一个隐藏的 a 标签,href 为输出流,设置 download
dom.style.display = 'none'
dom.href = url
dom.setAttribute('download', fileName) // 指示浏览器下载 url,而不是导航到它;因此将提示用户将其保存为本地文件
document.body.appendChild(dom)
dom.click()
document.body.removeChild(dom) // 下载完成移除元素
window.URL.revokeObjectURL(url) // 释放掉 blob 对象
}
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 工程化
# requestDownload.js
import axios from 'axios'
import { Message } from 'element-ui'
import store from '@/store'
// create an axios instance
const service = axios.create({
baseURL: '请求地址', // process.env.VUE_APP_BASE_API; url = base url + request url;
withCredentials: true, // 表示跨域请求时是否需要使用凭证
responseType: 'blob' // 接收返回的类型
})
/**
* HTTP方法
*/
// request interceptor
service.interceptors.request.use(
config => {
// do something before request is sent
if (store.getters.token) {
// let each request carry token --['X-Token'] as a custom key.
// please modify it according to the actual situation.
config.headers['token'] = store.getters.token
}
return config
},
error => {
// do something with request error
Message({
message: '文件不存在',
type: 'error',
duration: 5 * 1000
}) // for debug
return Promise.reject(error)
}
)
// response interceptor
service.interceptors.response.use(
/**
* If you want to get information such as headers or status
* Please return response => response
*/
/**
* Determine the request status by custom code
* Here is just an example
* You can also judge the status by HTTP Status Code.
*/
response => {
if (!response.data) {
return Promise.reject('文件不存在')
} else {
return response.data
}
},
error => {
// console.log('err' + error) // for debug
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service
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
67
68
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
67
68
# 处理流的方法
// 处理下载流
export function download(content, fileName) {
const blob = new Blob([content]) // 创建一个类文件对象:Blob 对象表示一个不可变的、原始数据的类文件对象
const url = window.URL.createObjectURL(blob) // URL.createObjectURL(object) 表示生成一个 File 对象或 Blob 对象
let dom = document.createElement('a') // 设置一个隐藏的 a 标签,href 为输出流,设置 download
dom.style.display = 'none'
dom.href = url
dom.setAttribute('download', fileName) // 指示浏览器下载 url,而不是导航到它;因此将提示用户将其保存为本地文件
document.body.appendChild(dom)
dom.click()
document.body.removeChild(dom) // 下载完成移除元素
window.URL.revokeObjectURL(url) // 释放掉 blob 对象
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 接口示例
import requestDownload from '@/utils/requestDownload'
export function exportFile(data) {
return requestDownload({
url: '/excel/excelDownLoad',
method: 'post',
data: data
})
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 使用示例
import { exportFile } from '@/api/**.js'
import { download } from '@/utils/index.js'
exportFile({
id: 1
}).then(result => {
download(result, '模板文件.xlsx')
})
1
2
3
4
5
6
7
2
3
4
5
6
7
# 参考资料
编辑 (opens new window)
上次更新: 5/27/2023, 1:02:05 PM