Vue 项目非 proxy 实现访问不同微服务

本贴最后更新于 1340 天前,其中的信息可能已经沧海桑田

背景

最近做的一个项目,由于甲方的奇葩要求:

前端 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);
    }
}

非前端开发,小小后端程序员,目前只能想到这种方式了。

  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    266 引用 • 665 回帖
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    944 引用 • 1459 回帖 • 17 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...