interceptors
// Add a request interceptor
axios.interceptors.request.use(function (config) {
// 这里会最先拿到请求配置,config 对象具体属性见:https://github.com/axios/axios#request-config
return config;
}, function (error) {
// 这里极少情况会进来,暂时没有找到主动触发的方法
return Promise.reject(error);
});
// Add a response interceptor
axios.interceptors.response.use(function (response) {
// 1. http 状态码是 2xx 会进来这里,response 的数据结构如下:response-200
// 2. 可通过 validateStatus 配置进到 success callback 的 http status,例如:
// function (status) {
// return status >= 200 && status <= 500; // 当 http status 属于定义的范围内,都会进到 success callback
// }
return response;
}, function (error) {
// 1. http 状态码非2开头(没有额外定义 validateStatus)的都会进来这里,如 404, 500 等,error 的数据结构如下:error-400、error-500
// 2. 取消请求也会进入这里,可以用 axios.isCancel(error) 来判断是否是取消请求,error 的数据结构如下:cancel-error
// 3. 请求运行有异常也会进入这里,如故意将 headers 写错:axios.defaults.headers = '123'
// 4. 断网,error 的数据结构如下:network-error
return Promise.reject(error);
});
判断 axios error
function onError(e) {
if (e.response) {
// 请求已发出,服务器返回的 http 状态码不是 2xx,例如:400,500,对应上面的 1
console.info(e.response)
} else if (e.request) {
// 请求已发出,但没有收到响应,例如:断网,对应上面的 4
console.info(e.request)
} else {
// 请求被取消或者发送请求时异常,对应上面的 2 & 3
console.info('error', e.message)
}
return Promise.reject(error);
}
function onSuccess(res) {
return res
}
axios.interceptors.response.use(onSuccess, onError);
error & response
// error-400
error: {
config: {…}, // config 对象具体属性见:https://github.com/axios/axios#request-confi
request: XMLHttpRequest {…}, // 一个 XMLHttpRequest 对象
response: {
config: {…},
data: null,
headers: {…},
request: XMLHttpRequest {…},
status: 400, // HTTP status code
statusText: "Bad Request", // HTTP status message
}
message: "Request failed with status code 400",
stack: "Error: Request failed with status code 400",
}
// error-500
error: {
config: {…},
request: XMLHttpRequest {…}, // 一个 XMLHttpRequest 对象
response: {
config: {…},
data: null,
headers: {…},
request: XMLHttpRequest {…},
status: 500, // HTTP status code
statusText: "Internal Server Error", // HTTP status message
}
message: "Request failed with status code 500",
stack: "Error: Request failed with status code 500",
}
// network-error
error: {
config: {…},
request: XMLHttpRequest {…}, // 一个 XMLHttpRequest 对象
response: undefined,
message: "Network Error",
stack: "Error: Network Error",
}
// cancel-error
error: {
message: "Operation canceled by the user."
}
// response-200
response: {
config: {…},
data: {…}, // 里面是后台自定义的数据结构,例如:{ code, msg, result }
headers: {…},
request: XMLHttpRequest {…},
status: 200, // HTTP status code
statusText: "OK", // HTTP status message
}
demo
demo: 需要在页面展示一个选择下拉框,数据从接口返回。
<template>
<el-select v-model="value" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</template>
<script>
import fetchCategories from './api'
export default {
data() {
return {
options: [],
value: ''
}
},
methods: {
getCategories() {
fetchCategories()
}
},
created() {
this.getCategories().then(res => {
this.options = res
})
}
}
</script>
// api.js
// demo1
export async function fetchCategories() {
const { data } = await axios.get('/api/mydata/shop/category/')
return data.result && data.result.list
}
// demo2
export async function fetchCategories() {
try {
const { data } = await axios.get('/api/mydata/shop/category/')
return data.result && data.result.list
} catch(e) {
return []
}
}
如果没有用 try-catch(api.js - demo1),当 axios.get 出错时,程序会停止运行,return xxx 不会被执行,此时函数返回的是一个 pending promise。
因此需要用 try-catch 包裹 await axis.get(xxx)(api.js - demo2),当 axios.get 出错时被 catch,此时函数返回的是一个 promise { status: 'resolved', value: [] },options 被赋值成一个空数组。