在react和vue都一般都會(huì)使用一個(gè)全局的request方法進(jìn)行http請(qǐng)求
在該方法中需要對(duì)200之外的狀態(tài)碼進(jìn)行單獨(dú)處理
參考ant pro項(xiàng)目中代碼 改寫(xiě)的axios配置
狀態(tài)碼設(shè)置
// axiosSetting.js
import axios from 'axios'
import { message } from 'antd'
import { routerRedux} from 'dva/router'
import { getToken } from './auth'
import store from '../index'
axios.defaults.withCredentials = true
axios.defaults.timeout = 10000
const codeMessage = {
200: '服務(wù)器成功返回請(qǐng)求的數(shù)據(jù)。',
201: '新建或修改數(shù)據(jù)成功。',
202: '一個(gè)請(qǐng)求已經(jīng)進(jìn)入后臺(tái)排隊(duì)(異步任務(wù))。',
204: '刪除數(shù)據(jù)成功。',
400: '發(fā)出的請(qǐng)求有錯(cuò)誤,服務(wù)器沒(méi)有進(jìn)行新建或修改數(shù)據(jù)的操作。',
401: '用戶沒(méi)有權(quán)限(令牌、用戶名、密碼錯(cuò)誤)。',
403: '用戶得到授權(quán),但是訪問(wèn)是被禁止的。',
404: '發(fā)出的請(qǐng)求針對(duì)的是不存在的記錄,服務(wù)器沒(méi)有進(jìn)行操作。',
406: '請(qǐng)求的格式不可得。',
410: '請(qǐng)求的資源被永久刪除,且不會(huì)再得到的。',
422: '當(dāng)創(chuàng)建一個(gè)對(duì)象時(shí),發(fā)生一個(gè)驗(yàn)證錯(cuò)誤。',
500: '服務(wù)器發(fā)生錯(cuò)誤,請(qǐng)檢查服務(wù)器。',
502: '網(wǎng)關(guān)錯(cuò)誤。',
503: '服務(wù)不可用,服務(wù)器暫時(shí)過(guò)載或維護(hù)。',
504: '網(wǎng)關(guān)超時(shí)。',
}
axios攔截
// axiosSetting.js
// request攔截器
axios.interceptors.request.use(
config => {
// Do something before request is sent
const token = getToken()
// console.log(window.location.href.indexOf('/user/login') > -1)
if(config.url.indexOf('/auth/oauth/token') > 0){
config.headers.Authorization = 'Basic dnVlOnZ1ZQ==' // 增加客戶端認(rèn)證
}else{
config.headers.Authorization = token // 讓每個(gè)請(qǐng)求攜帶token--['X-Token']為自定義key 請(qǐng)根據(jù)實(shí)際情況自行修改
}
const {url} = config
if(/^\/api\//.test(url) && !token && !window.location.href.indexOf('user') > -1){
const { dispatch } = store
dispatch(routerRedux.replace('/user/login')) // 跳轉(zhuǎn)到登錄頁(yè)
}
return config
},
error => {
// Do something with request error
console.log(error) // for debug
Promise.reject(error)
}
)
// respone攔截器
axios.interceptors.response.use(
response => {
/**
* 下面的注釋為通過(guò)response自定義code來(lái)標(biāo)示請(qǐng)求狀態(tài),當(dāng)code返回如下情況為權(quán)限有問(wèn)題,登出并返回到登錄頁(yè)
* 如通過(guò)xmlhttprequest 狀態(tài)碼標(biāo)識(shí) 邏輯可寫(xiě)在下面error中
*/
const res = response.data
// if (response.status === 401 || res.status === 40101) {
// MessageBox.confirm('你已被登出,可以取消繼續(xù)留在該頁(yè)面,或者重新登錄', '確定登出', {
// confirmButtonText: '重新登錄',
// cancelButtonText: '取消',
// type: 'warning'
// }).then(() => {
// store.dispatch('LogOut').then(() => {
// location.reload() // 為了重新實(shí)例化vue-router對(duì)象 避免bug
// })
// })
// return Promise.reject('error')
// }
// if (res.status === 30101) {
// Message({
// message: res.message,
// type: 'error',
// duration: 5 * 1000
// })
// return Promise.reject('error')
// }
// if (res.status === 40301) {
// Message({
// message: '當(dāng)前用戶無(wú)相關(guān)操作權(quán)限!',
// type: 'error',
// duration: 5 * 1000
// })
// return Promise.reject('error')
// }
if (response.status !== 200 && res.status !== 200) {
message.error(response.data.message)
// notification.error({
// message: res.status,
// description: res.message,
// })
} else {
return response.data
}
},
error => {
// console.log(JSON.stringify(error)) // for debug
if (error === undefined || error.code === 'ECONNABORTED') {
message.warning('服務(wù)請(qǐng)求超時(shí)')
return Promise.reject(error)
}
const { response: { status, statusText, data: { msg = '服務(wù)器發(fā)生錯(cuò)誤' } }} = error
const { response } = error
const { dispatch } = store
const text = codeMessage[status] || statusText || msg
if (status === 400) {
// message.warning('賬戶或密碼錯(cuò)誤!')
dispatch(routerRedux.push('/user/login'))
}
const info = response.data
if (status === 401 || info.status === 40101) {
dispatch({
type: 'login/logout',
})
// MessageBox.confirm('你已被登出,可以取消繼續(xù)留在該頁(yè)面,或者重新登錄', '確定登出', {
// confirmButtonText: '重新登錄',
// cancelButtonText: '取消',
// type: 'warning',
// }).then(() => {
// store.dispatch('LogOut').then(() => {
// location.reload() // 為了重新實(shí)例化vue-router對(duì)象 避免bug
// })
// })
}
if (status === 403) {
dispatch(routerRedux.push('/exception/403'))
// Notification.warning({
// title: '禁止',
// message: info.message,
// type: 'error',
// duration: 2 * 1000,
// })
}
if (info.status === 30101) {
dispatch(routerRedux.push('/exception/500'))
// Notification.warning({
// title: '失敗',
// message: info.message,
// type: 'error',
// duration: 2 * 1000,
// })
}
if (response.status === 504) {
dispatch(routerRedux.push('/exception/500'))
// Message({
// message: '后端服務(wù)異常,請(qǐng)聯(lián)系管理員!',
// type: 'error',
// duration: 5 * 1000,
// })
}
message.error(`${status}:${text}`)
// throw error
// return error
return Promise.reject(error)
}
)
調(diào)用并導(dǎo)出axios
// request.js
import axios from 'axios'
import { merge } from 'lodash'
import './axiosSetting'
const request = async (_options) => {
// 默認(rèn)GET方法
const method = _options.method || 'GET'
const options = merge(
{ ..._options },
{
method,
}
)
return axios(options)
}
/**
* 封裝get請(qǐng)求
* @param { String } url 請(qǐng)求路徑
* @param { Object } 請(qǐng)求參數(shù)
* params GET請(qǐng)求參數(shù)
*/
const get = (url, params, _options) => {
return request({ ..._options, params, url })
}
/**
* 封裝post請(qǐng)求
* @param { Object } 請(qǐng)求參數(shù)
* data POST請(qǐng)求請(qǐng)求參數(shù),對(duì)象形式
*/
const post = (url, data, _options) => {
return request({ ..._options, data, url }, 'POST')
}
export { get, post }
export default request