背景
在实际应用场景中,假如有一个下载或者导出请求,数据量非常大的情况下,接口响应的会很慢,这时候我我们想中断请求,该怎么做呢?
我们先来看一下axios官方给出的请求中断的方法 axios请求中断 axios中文网
方法一:传入canceltoken
传入canceltoken,在页面调用request.cancel('中断请求')
api请求代码: axios代码封装request.js
import axios from 'axios'
import { message, messagebox } from 'element-ui'
import store from '@/store'
import { gettoken } from '@/utils/auth'
const service = axios.create({
baseurl: process.env.vue_app_api,
timeout: 1800000
})
// 请求拦截
service.interceptors.request.use(
config => {
if (store.getters.token) {
config.headers['authorization'] = gettoken()
}
return config
},
error => {
return promise.reject(error)
}
)
// 响应拦截
service.interceptors.response.use(
response => {
const res = response.data
if (!res.status && response.status === 200) {
return response
}
if (res.status !== '200') {
message({
message: res.message || 'error',
type: 'error',
duration: 5 * 1000,
dangerouslyusehtmlstring: true
})
if (res.status === '401') {
messagebox.confirm('访问了未授权的资源或者登入状态已失效,你可以继续留在这个页面,或者重新登入', '是否重新登入', {
confirmbuttontext: '重新登入',
cancelbuttontext: '取消',
type: 'warning'
}).then(() => {
// 清空token,并且重新登入
store.dispatch('user/resettoken').then(() => {
location.reload()
})
})
}
return promise.reject(new error(res.message || 'error'))
} else {
return res
}
},
error => {
if (error.response && error.response.status === 401) {
messagebox.confirm('提示', '是否重新登入', {
confirmbuttontext: '重新登入',
cancelbuttontext: '取消',
type: 'warning'
}).then(() => {
// 清空token,并且重新登入
store.dispatch('user/resettoken').then(() => {
location.reload()
})
}
return true
} else if (error.response && error.response.status === 502) {
message({
message: '502 系统正在重新发布中,请稍后再试',
type: 'error',
duration: 5 * 1000
})
} else if (error.response && error.response.status === 404) {
message({
message: '404 系统正在重新发布中或请求不存在,请稍后再试',
type: 'error',
duration: 5 * 1000
})
} else {
message({
message: error.message,
type: 'error',
duration: 5 * 1000,
dangerouslyusehtmlstring: true
})
}
return promise.reject(error)
}
)
// api.js
import request from '@/utils/request'
// 这是一个导出接口
export function export(data, canceltoken) {
return request({
url: '/order/order-export',
method: 'post',
responsetype: 'blob',
data,
canceltoken
})
在页面中调用接口
<button @click='exportdata'>导出</button>
<button @click='handlecancel'>取消</button>
import {export} from '@/api.js'
import axios from 'axios'
data() {
return {
request:null
}
}
methods:{
// 导出
exportdata() {
const request = axios.canceltoken.source()
this.request = request
export({},request.token)
.then(res => {})
.catch((err) => {})
},
//取消
handlecancel () {
this.request.cancel('中断请求')
}
}
方法二:abortcontroller
此方法必须要求axios的版本最低是v0.22.0,否则不生效 还是上面的代码,做以下修改:
// api.js
export function exportdata(data) {
return request({
url: '/order/order-export',
method: 'post',
responsetype: 'blob',
data,
signal: data.signal // 新加的代码
})
}
// 页面中使用
import {export} from '@/api.js'
import axios from 'axios'
let controller;
methods:{
// 导出
exportdata() {
controller = new abortcontroller()
export({singal:controller.singal}).then(res => {
console.log('下载成功')
})
.catch((err) => {
if (axios.iscancel(err)) {
console.log('下载被取消')
} else if (err.name === 'aborterror') {
console.log('下载被中止')
} else {
console.error(`下载错误:${err.message}`)
}
})
},
//取消
handlecancel () {
if (controller) {
controller.abort() // 使用 abort 方法中止下载 console.log('中止导出')
}
}
}
多个请求的取消
此方法利用 fetch api 方式—— abortcontroller 取消请求:
首先要对request.js的封装做出修改
// 取消请求
export const abortrequest = (controller) => {
if (controller) {
controller.abort()
}
}
// 请求拦截
service.interceptors.request.use(
(config) => {
if (config.abortcontroller) {
config.signal = config.abortcontroller.signal
}
...其他代码跟上面一样
return config
})
// api.js
export function download(data, abortcontroller) {
return request({
url: '/order/order-download',
method: 'post',
responsetype: 'blob',
data,
abortcontroller // 新加的代码
})
}
export function exportdata(data,abortcontroller) {
return request({
url: '/order/order-export',
method: 'post',
responsetype: 'blob',
data,
abortcontroller // 新加的代码
})
}
在页面中使用
<div>
<button @click="fetchdata1">发起请求 1</button>
<button @click="abortdownload1">中止请求 1</button>
<button @click="fetchdata2">发起请求 2</button>
<button @click="abortdownload2">中止请求 2</button>
</div>
let controller1;
let controller2;
import {abortrequest} from '@/utils/request.js'
import {exportdata,download} from '@/api'
methods:{
// 取消请求1
abortdownload1() {
abortrequest(controller1)
}
// 取消请求2
abortdownload2() {
abortrequest(controller2)
}
// 发起请求1
fetchdata1() {
controller1 = new abortcontroller()
const abortcontroller = controller1
exportdata(data,abortcontroller).then(res => {
console.log('成功')
})
.catch(err => {
if (axios.iscancel(err)) {
console.log('下载被取消')
common.showmessage(this, '到导出取消', 'warning')
} else if (err.name === 'aborterror') {
console.log('下载被中止')
} else {
console.error(`下载错误:${err.message}`)
}
})
},
fetchdata2() {
controller2 = new abortcontroller()
const abortcontroller = controller2
download(data,abortcontroller).then(res => {
console.log('成功')
})
.catch(err => {
if (axios.iscancel(err)) {
console.log('下载被取消')
common.showmessage(this, '到导出取消', 'warning')
} else if (err.name === 'aborterror') {
console.log('下载被中止')
} else {
console.error(`下载错误:${err.message}`)
}
})
},
}
到此这篇关于axios请求中断的几种方法的文章就介绍到这了,更多相关axios请求中断内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论