当使用axios在Vue中进行数据请求时,可能会遇到服务器响应非常缓慢或者出现网络问题等情况,由此导致前端请求一直在等待响应,造成用户体验不佳。为了解决这类问题,我们可以通过设置axios的timeout超时时间来规定前端在等待响应的最大时间,如果超过这个时间则取消请求,并且返回一个错误提示。
下面是设置axios timeout的完整攻略和两条示例说明:
设置全局 timeout
我们可以通过axios的默认配置来全局设置timeout,这样所有的axios请求都会拥有相同的超时时间,可以在Vue项目中的main.js中进行如下设置:
import axios from 'axios'
axios.defaults.timeout = 10000 // 设置默认的超时时间,单位是毫秒
Vue.prototype.$http = axios
在上述代码中,我们将axios请求的默认超时时间设置为10秒。如果我们在实际请求中不需要设置其他超时时间,就可以直接使用该全局配置。
设置单个请求的 timeout
有时候我们可能需要针对某个特定的请求来设置超时时间。在这种情况下,我们可以在请求的config中增加一个timeout属性来设置超时时间,如下所示:
axios.get('/api/user', {
params: {
id: 12345
},
timeout: 5000 // 设置该请求的超时时间为5秒
}).then(response => {
console.log(response.data)
}).catch(error => {
console.log(error.message)
})
上述代码中,我们在get请求的config中增加了timeout属性,并将超时时间设置为5秒。
示例1:完整代码
<template>
<div>
{{ message }}
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'Example',
data() {
return {
message: ''
}
},
created() {
axios.get('/api/user', {
params: {
id: 12345
},
timeout: 5000
}).then(response => {
this.message = response.data
}).catch(error => {
console.log(error.message)
})
}
}
</script>
上述代码中,我们在Vue组件的created生命周期中发送了一个get请求,并设置了超时时间为5秒。请求成功后,将响应结果赋值给组件中的message。
示例2:防止超时重复发送
在实际使用中,可能会遇到在请求超时之后,希望重新发送请求的情况。这时候我们可以在axios的interceptors拦截器中进行处理。
axios.interceptors.response.use(
response => {
return response
},
error => {
if (axios.isCancel(error)) {
console.log('Request canceled:', error.message)
} else if (error.code === 'ECONNABORTED') {
console.log('Request timeout!')
handleTimeout(error.config) // 处理超时事件
} else {
console.log('Request error:', error.message)
return Promise.reject(error)
}
}
)
let pendingRequests = new Map() // 存储正在进行的请求
let CancelToken = axios.CancelToken
function handleTimeout(config) {
let key = getRequestKey(config)
let request = pendingRequests.get(key)
if (request) {
request.cancel('Timeout!') // 取消该请求
pendingRequests.delete(key)
sendRequest(config) // 重新发送请求
}
}
function getRequestKey(config) {
return [config.method, config.url, JSON.stringify(config.params)].join('&')
}
function sendRequest(config) {
let key = getRequestKey(config)
let request = axios.request(config)
request.then(response => {
pendingRequests.delete(key)
return response
}).catch(error => {
pendingRequests.delete(key)
return Promise.reject(error)
})
pendingRequests.set(key, request)
}
export default {
get(url, params, timeout = 5000) {
let config = {
method: 'get',
url: url,
params: params,
timeout: timeout,
cancelToken: new CancelToken(function executor(cancel) {
let key = getRequestKey(config)
if (pendingRequests.has(key)) {
cancel('Request canceled')
} else {
pendingRequests.set(key, {cancel})
}
})
}
return sendRequest(config)
},
post(url, data, timeout = 5000) {
let config = {
method: 'post',
url: url,
data: data,
timeout: timeout,
cancelToken: new CancelToken(function executor(cancel) {
let key = getRequestKey(config)
if (pendingRequests.has(key)) {
cancel('Request canceled')
} else {
pendingRequests.set(key, {cancel})
}
})
}
return sendRequest(config)
}
}
上述代码中我们使用了一个pendingRequests的Map来存储正在进行的请求,每个请求的key是由请求的method、url和params组成的。当第一次发送一个请求时,我们将它加入pendingRequests中,同时创建一个cancelToken,并在cancelToken中设置一个executor,在executor中判断该请求是否已经在pendingRequests中存在。如果已经存在则调用其cancel方法取消请求。如果不存在就将一个{cancel}对象加入pendingRequests中。
当请求超时后,我们可以在拦截器的错误处理函数中通过判断error.code是否为‘ECONNABORTED’来判断该请求是否超时。如果请求超时,我们可以通过getRequestKey函数获取该请求的key,并在pendingRequests中获取该请求对象。然后我们会取消该请求,并调用sendRequest函数重新发送同样的请求,并更新pendingRequests。
最后,我们在axios使用过程中不再调用axios的方法,而是调用我们自身的get和post方法,这两个方法内部包含了超时重发的逻辑。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:在vue中axios设置timeout超时的操作 - Python技术站