umi前后端交互技术,通用型request配置
在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 };