当前位置: 首页 > article >正文

微前端 - 对外只开放一个端口

问题

按原来的微前端部署形式,需要对外开放N(子系统个数)+1(主应用)个端口,存在网络安全的问题。
注意:此处不考虑https的问题,如需考虑,参考http即可。

目标

  • 1、减少对外开放的端口
  • 2、保证子系统能独立更新部署和访问

方案

为了保证子系统仍然是独立的,那么每个子系统必定对应一个NGINX(一个端口),但是此端口可以考虑不对外部网络开放,通过主应用的NGINX进行内部跳转。

步骤

一、处理主应用

registerMicroApps(
  [
    {
      name: 'SubSystem',
      entry: '//IP:PORT',
      container: '#subContainer',
      activeRule: '/micro/sub-system'
    }
  ],
  {
  // 其实挂载子系统的速度很快,loading应该做到各个子系统中去。
  beforeLoad: (app) => { // 子应用加载前
    console.log('beforeLoad 子应用加载前')
  },
  afterMount: async (app) => { // 子应用完成加载后
    console.log('afterMount 子应用完成加载后')
  },
  beforeMount: (app) => {
    // 每次加载子系统都执行
  }
})

registerMicroApps(
  [
    {
      name: 'SubSystem',
      entry: '/micro-system/',
      container: '#subContainer',
      activeRule: '/micro/sub-system'
    }
  ],
  {
  // 其实挂载子系统的速度很快,loading应该做到各个子系统中去。
  beforeLoad: (app) => { // 子应用加载前
    console.log('beforeLoad 子应用加载前')
  },
  afterMount: async (app) => { // 子应用完成加载后
    console.log('afterMount 子应用完成加载后')
  },
  beforeMount: (app) => {
    // 每次加载子系统都执行
  }
})

将原本entry: '//IP:PORT',子系统入口跳转至子系统的IP和端口配置,改为entry: '/micro-system/',跳转至/micro-system/通过NGINX去拦截跳转内部服务器IP和端口。

二、处理子系统

  • 通过主应用访问子应用,加载子应用js资源
  • http://主应用IP:主应用端口/micro-system/js/chunk-vendors.********.js
  • 通过NGINX去拦截跳转内部子应用服务器IP和端口
  • http://子应用IP:子应用端口/micro-system/js/chunk-vendors.********.js

如果子应用不做任何改动,是访问不到资源的。

方案1,行不通

将子应用拦截/micro-system/在转发重写URL时去掉,然而测试现象是加载冲突,无法正确转发加载到资源。
请添加图片描述
通过F12查看,资源好像是访问到9000(主应用端口)下的了。

方案2,可行

在不重写去掉/micro-system/的前提下,资源能正常访问,则需给子系统所有资源路径加上前缀。

2.1、vue.config.js打包配置文件

追加publicPath属性:

publicPath: '/micro-system/',

该配置的意思是,子系统打包后的所有资源路径前缀加上/micro-system/。

2.2、qiankun的子应用配置文件

export const render = (props = {}) => {
  const { container } = props
  router = new VueRouter({
    base: window.__POWERED_BY_QIANKUN__ ? '/micro/sub-system/' : '/',
    mode: 'history',
    routes
  })
  instance = new Vue({
    router,
    store,
    render: h => h(App)
  }).$mount(container ? container.querySelector('#app') : '#app')
}

export const render = (props = {}) => {
  const { container } = props
  router = new VueRouter({
    base: window.__POWERED_BY_QIANKUN__ ? '/micro/sub-system/' : '/micro-system/',
    mode: 'history',
    routes
  })
  instance = new Vue({
    router,
    store,
    render: h => h(App)
  }).$mount(container ? container.querySelector('#app') : '#app')
}

在不是通过主应用访问时,即单独访问子系统时,为路由的base追加/micro-system/。
因为vue.config.js的配置,打包后的子系统资源前缀都加上了/micro-system/,此处访问资源也需要加上不然无法正确获取资源。

三、本地部署测试

3.1、主应用需要添加拦截跳转

proxy: {
  '/micro-system/': {
    target: 'http://localhost:9001/',
    changeOrigin: false,
    secure: false
  },

走主应用访问时资源,通过/micro-system/拦截,跳转子系统部署的IP和端口,此IP和端口可以不对外网开放。
可参考后台接口请求的拦截跳转。
资源加载:
请添加图片描述
加载效果:
请添加图片描述

3.2、子系统无需修改

但需要注意的是,访问的时候必须在端口后追加/micro-system/。
请添加图片描述

  • 原来访问地址:
  • http://localhost:9001/login
  • 现在访问地址:
  • http://localhost:9000/micro-system/login(通过主应用端口访问子系统)
  • http://localhost:9001/micro-system/login(直接访问子系统)

此时,你会发现所有的资源访问后面都多了/micro-system/。
请添加图片描述

四、服务器部署测试

4.1、主应用NGINX追加子系统拦截

location /micro-system/ {
  proxy_pass http://IP:PORT/micro-system/;
  proxy_set_header Host $host:$server_port;
}

走主应用访问时资源,通过/micro-system/拦截,跳转子系统部署的IP和端口,此IP和端口可以不对外网开放。
可参考后台接口请求的拦截跳转。
注意:原来的~*拦截(如果有的话)需要去掉,不然子系统的资源会被抢先拦截。

4.2、子系统NGINX拦截配置如下

location /micro-system/ {
    try_files $uri $uri/ /micro-system/index.html;
    alias /usr/share/nginx/html/;
    index index.html index.htm;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
  }

注意:

  • a)、原来的location / 拦截和~*拦截(如果有的话)可以去掉了,因为所有的资源都在/micro-system/下。
  • b)、本案例是通过docker容器管理NGINX的,在docker配置中,有将实际的dist包文件映射到/usr/share/nginx/html/。
- ./bpg-sub-system/web/dist:/usr/share/nginx/html

其实只需要将alias别名指向子系统dist包的位置即可。

结论

  • 如果子应用部署的服务器端口,提供对外访问:
    那么可以直接访问,只需要在端口后追加子系统拦截标识,即公共路径publicPath的配置即可。
  • 如果子应用部署的服务器端口,不对外提供访问:
    那么可以通过访问主应用的IP和端口,追加子系统拦截标识,同样可以通过NGINX转发的方式加载资源。
    (类比接口调用,通常后台接口的服务器是不开放对外直接访问的,需要通过NGINX转发。)
    此时,只需要对外提供主应用的端口,本案例是9000即可。
    当然了如果有HTTPS那就再加一个。

http://www.kler.cn/a/299985.html

相关文章:

  • 23. C 语言,%d 和 %i的区别
  • Python 数据分析— Pandas 基本操作(下)
  • react js 笔记 3
  • 获取时间,并将时间按一定的格式输出
  • C++:sort自动排序函数
  • cell phone teardown 手机拆卸
  • nvm只有iojs列表解决办法
  • from T2I to T2V
  • 构建响应式 Web 应用:Vue.js 基础指南
  • Kubernetes资源管理常用的标签分类有哪些?
  • IT前端好用的工具集
  • 【科研小白系列】使用screen创建虚拟终端,实现本地关机后服务器仍然跑模型
  • Elasticsearch 使用误区之五——单次请求获取大量数据
  • 实时系统资源监测:AutoPowerOptionsOK确保电脑性能与节能兼备
  • SpringBoot中利用EasyExcel+aop实现一个通用Excel导出功能
  • Mysql 数据库免费使用
  • windows七个消息队列
  • 基于springboot的校园志愿者管理系统的设计与实现 (含源码+sql+视频导入教程+论文+PPT)
  • 数学基础 -- 线性代数之格拉姆-施密特正交化
  • DNAT和SNAT实践