部署多台服务器,动态配置前端请求的IP地址
【入口文件】
index.ts
import prod from './prod';
import dev from './dev';
const nodeEnv = process.env.NODE_ENV;
let config;
if (nodeEnv === 'production') {
config = prod;
} else {
config = dev;
}
export default config;
【开发环境development】
dev.ts
export default {
apiBase: 'http://xxx.xxx.xx.xx/api/',
wsBase: 'ws://xxx.xxx.xx.xx:xxxx',
};
【生产环境production】
prod.ts
export default {
apiBase: '',
};
【调用】
可写在请求拦截器处,request.ts
当发送请求时先判断如果是development环境,就直接调用本地dev.ts中的apiBase,否则自动拼接线上ip+/api/
另一种,如果不仅有http请求,还有websocket请求,且也为动态ip地址,同理可采用当development环境时就直接调用本地dev下的wsBase,否则上线时用主机ip拼接:8080 (我这里只是举例,具体拼接什么看后台同学给的地址)
【最后附上request.ts】
【含有请求拦截器写法哦】
import { extend } from 'umi-request';
import { message } from 'antd';
import config from '../config/dev';
import { history } from 'umi';
import { isFormData } from '@/utils';
const API_URL = config.apiBase;
const codeMessage = {
200: '服务器成功返回请求的数据',
201: '新建或修改数据成功',
202: '一个请求已经进入后台排队(异步任务)',
204: '删除数据成功',
400: '请求有误,服务器没有进行新建或修改数据的操作',
401: '用户名或密码错误',
403: '用户得到授权,但是访问是被禁止的',
404: '请求失败,结果不存在',
405: '操作失败',
406: '请求的格式不可得',
410: '请求的资源被永久删除',
422: '当创建对象时,发生验证错误',
500: '服务器发生错误,请检查服务器',
502: '网关错误',
503: '服务不可用,服务器暂时过载或维护',
504: '网关超时',
};
type mapCode =
| 200
| 201
| 202
| 204
| 400
| 401
| 403
| 404
| 405
| 406
| 410
| 422
| 500
| 502
| 503
| 504;
/**
* 异常处理程序
*/
const errorHandler = (error: { response: Response }): Response => {
const { response } = error;
console.log(response);
if (response && response.status) {
const errorText =
codeMessage[response.status as mapCode] || response.statusText;
const { status, url } = response;
message.error(`${errorText}`);
} else if (!response) {
message.error('无法连接服务器');
}
return response;
};
/**
* 配置request 请求时的默认参数
*/
// console.log(process.env.UMI_ENV,process.env.API_ROOT);
const request = extend({
timeout: 20000,
prefix: process.env.NODE_ENV === 'development' ? API_URL : '/api/',
errorHandler, // 默认错误处理
// credentials: 'include', // 默认请求是否带上cookie
});
// token 拦截器
request.interceptors.request.use((url: string, options: any) => {
let newOptions: any = { ...options };
const token = localStorage.getItem('token');
if (token) {
newOptions.headers['Authorization'] = token ? `Bearer ${token}` : null;
}
newOptions.headers['Content-Type'] = 'application/json';
if (isFormData(newOptions.body)) {
delete newOptions.headers['Content-Type'];
}
return {
url,
options: newOptions,
};
});
request.interceptors.response.use((response) => {
// const token = response.headers.get('access-token');
// if (token) {
// localStorage.setItem('access-token', token);
// }
// return response;
try {
const token = localStorage.getItem('token');
if (response.status === 401 && history.location.pathname === '/login') {
message.error('用户名或密码错误');
return;
}
if (
response.status === 401 ||
response.status === 403 ||
(!token && history.location.pathname !== '/login')
) {
// message.error('登录已过期,请重新登录');
localStorage.removeItem('token');
localStorage.removeItem('auth');
history.push('/login');
return;
}
} catch (error) {
return Promise.reject(error);
}
// console.log(response, 'response')
return response;
});
export default request;