在umi框架下進行開發,與后台交互可以使用自定義請求util,直接對fetch進行底層封裝,自主性強。也可以使用框架提供的request配置,更全面的進行開發。
使用自定義Util方式:requestUtils.jsx
1 //Author:guanghe
2 import {fetch} from 'dva'; 3 import {Modal} from 'antd'; 4
5 const assyParams = (obj) => { 6 let str = ''
7 for (let key in obj) { 8 const value = typeof obj[key] !== 'string' ? JSON.stringify(obj[key]) : obj[key] 9 str += '&' + key + '=' + value 10 } 11 return str.substr(1) 12 } 13
14 export function checkStatus(response) { 15 if (response.status >= 200 && response.status < 300) { 16 return response; 17 } 18 let err = new Error(response.statusText); 19 err.content = <>
20 <div>{response.status} {response.statusText}</div>
21 <div>{response.url}</div>
22 </>;
23 throw err; 24 } 25
26 export function checkResult(res, tip = false) { 27 if (res.code == 0) { 28 if(tip) { 29 Modal.success({ 30 title: "請求成功!", 31 content: <>{res.msg}</>
32 }); 33 } 34 return res.data; 35 } 36 let err = new Error(res.msg); 37 err.content = <>
38 {res.msg} 39 </>;
40 throw err; 41 } 42
43 //自己封裝的request,但推薦使用@@/plugin-request/request
44 export default function request(requestData, tip = false) { 45 let {url, method} = requestData; 46 let options = { 47 method, 48 headers: { 49 'Content-Type': 'application/json; charset=utf-8', 50 }, 51 credentials: 'include' //是否攜帶cookie,默認為omit不攜帶; same-origi同源攜帶; include同源跨域都攜帶
52 }; 53 if (method.toLowerCase() === 'get') { 54 url = requestData.url + '?' + assyParams(requestData.data); 55 } 56 if (method.toLowerCase() === 'post') { 57 options.body = JSON.stringify(requestData.data); 58 } 59 return fetch(url, options) 60 .then(checkStatus) 61 .then(response => response.json()) 62 .then((res) => checkResult(res, tip)) 63 .catch((err) => { 64 Modal.error({ 65 title: "請求異常!", 66 content: err.content 67 }); 68 }); 69 }
使用umi框架提供的request方式:app.ts
1 //Author:guanghe
2 import { RequestConfig } from 'umi'; 3 import {Modal} from 'antd'; 4
5 const codeMessage:{ [key: number]: string; } = { 6 200: '服務器成功返回請求的數據。', 7 201: '新建或修改數據成功。', 8 202: '一個請求已經進入后台排隊(異步任務)。', 9 204: '刪除數據成功。', 10 400: '發出的請求有錯誤,服務器沒有進行新建或修改數據的操作。', 11 401: '用戶沒有權限(令牌、用戶名、密碼錯誤)。', 12 403: '用戶得到授權,但是訪問是被禁止的。', 13 404: '發出的請求針對的是不存在的記錄,服務器沒有進行操作。', 14 406: '請求的格式不可得。', 15 410: '請求的資源被永久刪除,且不會再得到的。', 16 422: '當創建一個對象時,發生一個驗證錯誤。', 17 500: '服務器發生錯誤,請檢查服務器。', 18 502: '網關錯誤。', 19 503: '服務不可用,服務器暫時過載或維護。', 20 504: '網關超時。', 21 }; 22
23 interface error { 24 name:string, 25 data:any, 26 type: string, 27 response:{ 28 status:number, 29 statusText:string, 30 url:string 31 } 32 } 33
34 const errorHandler = (error:error) => { 35 //適配errorConfig中自定義的error
36 if(error.name==="BizError"){ 37 Modal.error({ 38 title: `請求錯誤 ${error.data.code}`, 39 content: error.data.msg, 40 }); 41 throw new Error(error.data.msg); 42 } 43 //適配網絡error,即error.name == "ResponseError"
44 const { response } = error; 45 const { status, url } = response; 46 let title = `請求錯誤 ${status}: ${url}`; 47 const content = codeMessage[response.status] || response.statusText; 48 Modal.error({ 49 title, 50 content, 51 }); 52 throw new Error(); 53 }; 54
55 export const request: RequestConfig = { 56 prefix: '/api/centerbusiness', 57 method: "post", 58 requestType: "form", 59 errorHandler, 60 errorConfig: { 61 adaptor: res => { 62 return { 63 //success為false,則umi拋出error.name為BizError的異常
64 success: res.code == 0, 65 }; 66 }, 67 }, 68 };