在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 };