跳到主要内容

青桔工作台 loadsh 架构设计方案

前言

封装特色:

  • 一段时间内,不允许发送重复请求
  • 批量接口路径通过对象模式有效管理

处理跨域

React 跨域

  1. 安装http-proxy-middleware依赖
yarn add http-proxy-middleware -S
  1. 根目录>src>setupProxy.js
const {createProxyMiddleware}=require('http-proxy-middleware');

module.exports=function(app){
app.use(createProxyMiddleware('/api',{
target:'http://localhost:4000',
changeOrigin:true,
pathRewrite:{
'^/api':''
}
}));
}

封装请求

import axios from 'axios';
import {mapValues,omit} from 'loadsh'

const {CancelToken}=axios;
const requestList=[];
const requestWait=3000;
const cancelRepeatRequest=function(requestList,url,cancel,errorMessage){
const errorMsg=errorMessage||'';
for(let i=0;i<requestList.length;i++){
if(requestList[i]===url){
cancel(errorMsg);
return;
}
}
requestList.push(url);
}
const allowRepeatRequest=function(requestList,url){
for(let i=0;i<requestList.length;i++){
requestList.splice(i,1);
break;
}
}
const request=axios.create({
baseURL:'/api',
timeout:1000,
withCredentials:true,
headers:{
'Content-Type':'application/json'
}
});

request.interceptors.request.use(
config=>{
let cancel;
config.cancelToken=new CancelToken(function(c){cancel=c});
cancelRepeatRequest(requestList,config.url,cancel,`${config.url}请求被中断`);
return config
},error=>{
return Promise.reject(error);
}
);
request.interceptors.response.use(
res=>{
setTimeout(()=>{
allowRepeatRequest(requestList,res.config.url);
},requestWait);
return res;
},
error=>{
if(error&&error.response){
const {status} =error.response;
switch(status){
case 400:{
error.message='错误请求';
break;
}
case 401:{
error.message='未授权,请重新登录!'
break;
}
case 403:{
error.message='请重新登录!'
break;
}
case 404:{
error.message='请求错误,未找到该资源!'
break;
}
case 405:{
error.message='请求方法未允许!'
break;
}
case 408:{
error.message='请求超时!'
break;
}
case 413:{
error.message='上传内容超出大小限制!'
break;
}
case 500:{
error.message='服务端错误!'
break;
}
case 501:{
error.message='网络未实现!'
break;
}
case 502:{
error.message='网络异常!'
break;
}
case 503:{
error.message='网络不可用!'
break;
}
case 504:{
error.message='网络超时!'
break;
}
case 505:{
error.message='http版本不支持该请求!'
break;
}
default:{
error.message=`连接错误${status}`
}
}
}
return Promise.reject(error);
}
);

export const requestTransform=config=>{
return mapValues(config,value=>{
let method;
let url;
if(typeof value==='string'){
url=value;
}else{
url=value.url;
method=value.method;
config=omit(value,['url','method']);
}
method=method||'get';
if(method==='get'){
return function(params){
return new Promise((resolve,reject)=>{
request[method](url,{params,...config}).then(result=>{
resolve(result.data);
}).catch(error=>{
reject(error)
});
});
}
}else if(method==='post'){
return function(params){
return new Promise((resolve,reject)=>{
request[method](url,params,config).then(result=>{
resolve(result.data);
}).catch(error=>{
reject(error)
});
});
}
}
})
}

export default request;

管理接口

import {requestTransform} from './request';

export default requestTransform({
login:{
url:'user/login',
method:'post'
},
logout:{
url:'user/logout',
method:"post"
},
// 对象写法
// findUser:{
// url:'/user/list',
// method:'get'
// },
// 字符串写法
findUser:'/user/list',
addUser:{
url:'/user/add',
method:'post'
}
});

:::

请求接口

:::details 根目录>src>app.js

import api from './server/api'

function findUser(){
api.findUser().then(res=>{
console.log(res);
});;
}
function addUser(){
const params={
userName:'杰斯',
age:19,
phone:'18235164568'
}
api.addUser(params).then(res=>{
console.log(res);
});
}
function App() {
return (
<div className="App">
<button onClick={findUser}>获取用户列表</button>
<button onClick={addUser}>添加用户</button>
</div>
);
}

export default App;