背景
最近做的一个项目,由于甲方的奇葩要求:
前端 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
module.exports = function combineURLs(baseURL, relativeURL) {
return relativeURL
? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
: baseURL;
};
实现
自己写一个类似的公共方法,每次请求之前,先拼接
//请求拼接方法
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 请求之前,调用方法
// 根据环境变量进行接口区分
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 = {}) {
//重点!!!请求前拼接,jurisdiction.js是自己封装公共方法的地方
url = jurisdiction.combineURLs(url)
return new Promise((resolve, reject) => {
axios.get(url, {
params
})
.then(response => {
if (response) {
resolve(response.data) // 成功
}
})
.catch(err => {
reject(err) // 失败
})
})
},
//post,put,delete类似
}
这样,在 api 里边,只需要写上不同的请求 URL 即可,如
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}`)
}
跨域
这样实现了动态拼接,只需要后端配置上跨域支持就行了
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
/**
* 配置跨域信息
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT", "OPTIONS")
.allowedHeaders("*")
.maxAge(3600);
}
}
非前端开发,小小后端程序员,目前只能想到这种方式了。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于