umi-request Ant Pro 的請求庫
阿新 • • 發佈:2020-08-26
umi-request
umi-request 是基於 fetch 的封裝,兼具 fetch 和 axios 的特點。旨在為開發者提供便捷統一的請求方式。Ant Pro 中對 其進行了初步的封裝。比如:統一的錯誤處理方式。
但是,在實際中我們可能會遇見各種各樣的情況,需要按照自己的需求對其進行封裝。那就首先從 Ant Pro 的統一的異常處理程式開始吧。
首先,引入umi-request的擴充套件到專案中。
import { extend } from 'umi-request';
其次,根據自己的專案實際情況定義錯誤碼和其對應的提示語。
const codeMessage = { 200: '伺服器成功返回請求的資料。', 201: '新建或修改資料成功。', 202: '一個請求已經進入後臺排隊(非同步任務)。', 204: '刪除資料成功。', 400: '發出的請求有錯誤,伺服器沒有進行新建或修改資料的操作。', 401: '使用者沒有許可權(令牌、使用者名稱、密碼錯誤)。', 403: '使用者得到授權,但是訪問是被禁止的。', 404: '發出的請求針對的是不存在的記錄,伺服器沒有進行操作。', 406: '請求的格式不可得。', 410: '請求的資源被永久刪除,且不會再得到的。', 422: '當建立一個物件時,發生一個驗證錯誤。', 500: '伺服器發生錯誤,請檢查伺服器。', 502: '閘道器錯誤。', 503: '服務不可用,伺服器暫時過載或維護。', 504: '閘道器超時。', };
然後,寫異常處理函式
/** * 異常處理程式 */ const errorHandler = (error: { response: Response }): Response => { const { response } = error; if (response && response.status) { const errorText = codeMessage[response.status] || response.statusText; const { status, url } = response; notification.error({ message: `請求錯誤 ${status}: ${url}`, description: errorText, }); } else if (!response) { notification.error({ description: '您的網路發生異常,無法連線伺服器', message: '網路異常', }); } return response; }; /** * 配置request請求時的預設引數 */ const request = extend({ errorHandler, // 預設錯誤處理 credentials: 'include', // 預設請求是否帶上cookie // timeout: 60000, // 請求超時 });
首先第一個需求:對請求結果異常的統一處理。比如:token 失效時,應該統一彈框提示,並且跳回到登入頁。非成功的統一提示。直接拿到後端返回的資料而去掉外層的包裝。
request.interceptors.response.use(async (response) => { const data = await response.clone().json(); // const currentInterface = getPureInterface(response.url); // 這個方法是為了得到純介面,然後可以適時的選擇跳過,或者做別的操作 // token 失效 if(data.code === 1014) { window.location.href = `${window.location.origin}/user/login`; } // 統一報錯資訊。需特殊跳過的介面可以在這裡跳過 if(data.code === 1009) { // ant 引入的元件 notification.error({ message: '請求錯誤', description: data.message, }) } return response; })
比如後端介面不同型別需要的引數格式不同。
// get 請求,引數拼接在 url 後面。並且需要在 headers 裡面新增引數 token
const requestGet = (url: string, data?: object) => {
return request.get(`${url}?${qs.stringify({ ...data, t: Date.now() })}`, {
headers: {
tokenId: getCookie("token"),
}
})
}
// post 請求,form 格式,每個請求都需要包含 token,accout 引數
const requestPost = (url: string, data?: object) => {
return request.post(url, {
method: 'POST',
data: {
...data,
tokenId: getCookie("token"),
account: getCookie("account"),
},
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
tokenId: getCookie("token"),
}
})
}
// post 請求,要求的入參卻是 json 格式
const requestPostJson = (url: string, data?: object) => {
return request.post(url, {
method: 'POST',
data,
headers: {
'Content-Type': 'application/json',
tokenId: getCookie("token"),
},
})
}
// 這是全域性的攔截,還可以寫區域性的攔截器
封裝完成之後,最後暴露出來即可使用
export default {
get: requestGet,
post: requestPost,
json: requestPostJson
};
比如請求前的攔截
/**
* 請求前攔截。比如新增資料或者,修改url
*/
request.interceptors.request.use( (url, options) => {
// console.log('url=',url)
// console.log('options', options)
/**
* 這裡的新增會在上面各自的請求之後執行,比如url 的拼接
* 這裡可以根據 options 的引數決定要不要修改或者拼接不同的前後綴
* options 包含 credentials、errorHandler、headers、method、params、
*/
return {
url: `xingquan${url}&author=guozheng`,
options: {...options, interceptors: true}
}
})
還有好多方便的用法,文件很詳細,使用到再補充。