背景 最近做的一个项目,由于甲方的奇葩要求:
前端Vue项目打包部署不能用nginx代理,需要走甲方提供的SLB,在请求不同的微服务时,需要带上SLB指定的微服务端口,由甲方配置SLB匹配不同端口,负载到相应微服务。
在之前项目开发中,我们都是通过nginx去匹配不同的location去做,或者是后端直接使用的spring cloud gateway,前端只需要配置http-proxy-middleware 或者直接请求spring cloud gateway网关就行。
而这次甲方的需求,后端不能用spring cloud gateway,必须前端请求微服务前就告诉SLB需要请求哪个微服务,故而有了今天的这个实现方式,可能不是最优,但是解决了目前的燃眉之急。
思路 在调用后端接口前,类似于nginx,根据不同的location匹配设置不同的端口,动态拼接到URL上,再去请求后端,参考了axios用helper下边的 combineURLs.js
1 2 3 4 5 module .exports = function combineURLs (baseURL, relativeURL ) { return relativeURL ? baseURL.replace (/\/+$/ , '' ) + '/' + relativeURL.replace (/^\/+/ , '' ) : baseURL; };
实现 自己写一个类似的公共方法,每次请求之前,先拼接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 combineURLs (relativeURL ) { let baseURL = axios.defaults .baseURL ; let port; if (relativeURL.startsWith ("/system" )) { port = 8081 ; } if (relativeURL.startsWith ("/mdm" )) { port = 8082 ; } if (relativeURL.startsWith ("/integration" )) { port = 8083 ; } if (relativeURL.startsWith ("/plan" )) { port = 8084 ; } if (relativeURL.startsWith ("/analysis" )) { port = 8085 ; } return relativeURL ? baseURL.replace (/\/+$/ , '' ) + ":" + port + "/" + relativeURL.replace (/^\/+/ , '' ) : baseURL; }
然后在封装的axios请求之前,调用方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 switch (process.env .NODE_ENV ) { case "dev" : axios.defaults .baseURL = 'http://localhost' ; break ; case "pro" : axios.defaults .baseURL = 'http://10.16.160.160' ; break ; } export default { get (url, params = {} ) { url = jurisdiction.combineURLs (url) return new Promise ((resolve, reject ) => { axios.get (url, { params }) .then (response => { if (response) { resolve (response.data ) } }) .catch (err => { reject (err) }) }) }, }
这样,在api里边,只需要写上不同的请求URL即可,如
1 2 3 4 5 export const Apis = { logs : params => req.post ("/system/logs/list" , params), users : params => req.post ("/system/users/list" , params), productionLine : params => req.get (`/mdm/productionLine/${params} ` ) }
跨域 这样实现了动态拼接,只需要后端配置上跨域支持就行了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addCorsMappings (CorsRegistry registry) { registry.addMapping("/**" ) .allowedOrigins("*" ) .allowCredentials(true ) .allowedMethods("GET" , "POST" , "DELETE" , "PUT" , "OPTIONS" ) .allowedHeaders("*" ) .maxAge(3600 ); } }
非前端开发,小小后端程序员,目前只能想到这种方式了。