Студенты, не знающие аксиомы, могут пойти сюда,Инструкция по использованию аксиом
Обратите внимание на следующие рекомендации по загрузке файловых потоков:
1. Сначала убедитесь, что бэкэнд имеет формат выходного потока
2. Тип данных ответа сервера axios — responseType:blob.
3. Возвращаемый поток данных занимает поле response.data
Пример:
axios({
method:'post',//请求方式
url:'请求地址',
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()
}
Конфигурация axios под инжиниринг выглядит следующим образом
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
Есть проблема с настройкой requestDownload.js: все возвраты возвращаются в виде блоба, и если токен истечет, он не будет проверен;
Способ улучшения следующий:
1, запрос.js
....request配置....
// response interceptor
service.interceptors.response.use(
response => {
const res = response.data
if (response.config.responseType === 'blob') {
return res
}
//假设res.code=0时,返回结果为succuss , res.code = 9008为token超时
if (res.code === 9008 ) {
Message({
message: '登录超时,请重新登录',
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error.message)
} else {
return res
}
},
error => {
// console.log('err' + error) // for debug
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service
2. Бэкэнд добавляет метод проверки тайм-аута токена
3. Файл интерфейса запроса: requestDownload.js инкапсулирует метод запроса.
import request from '@/utils/request'
async function requestDownload({ url, method, data }) {
await request({
url: '校验超时链接',
method: 'post'
})
return request({
url,
method,
data,
responseType: 'blob'//必填项
})
}
export default requestDownload
Добавлен публичный файл метода /util/index.js, метод обработки потока
//处理下载流
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()
}
Пример интерфейса добавления интерфейса загрузки в proAdd.js
import requestDownload from '@/utils/requestDownload'
export function exportFile(data) {
return requestDownload({
url: '/excel/excelDownLoad',
method: 'post',
data:data
})
}
Используйте образец exportExcelBtn.vue, чтобы добавить вызывающий метод.
import { exportFile } from '@/api/**.js'
import { download } from '@/utils/index.js'
exportFile({ id : 1 }).then(result => {
download(result, '模板文件.xlsx')
})
Улучшения обработки ошибок:
Возвращенный объект большого двоичного объекта имеет два свойства: размер и тип. Если типом является «application/json», большой двоичный объект можно считать и преобразовать в объект json.
//读取blob转换为json对象
var reader = new FileReader()
reader.onload = e => {
let data = JSON.parse(e.target.result)
console.log(data)
}
reader.readAsText(res.data)
Полный формат
....request配置....
// response interceptor
service.interceptors.response.use(
response => {
const res = response.data
if (response.config.responseType === 'blob') {
//判断若是json则代表返回错误,转成json
if(res.data.type === 'application/json'){
var reader = new FileReader()
reader.onload = e => {
let data = JSON.parse(e.target.result)
console.log(data)
//报错信息提示
Message({
message: data.message,
type: 'error',
duration: 5 * 1000
})
}
reader.readAsText(res.data)
} else {
return res
}
}
//假设res.code=0时,返回结果为succuss , res.code = 9008为token超时
if (res.code === 9008 ) {
Message({
message: '登录超时,请重新登录',
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error.message)
} else {
return res
}
},
error => {
// console.log('err' + error) // for debug
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service