跳到主要内容

微前端域名处理

  • 同域部署
  • 跨域部署
  • 子域名部署

同域部署​

同域部署是指主应用和所有子应用都部署在同一个域名下,通过不同的路径前缀来区分不同的应用

  • 优势:

    • 通信简单,可以直接使用window对象
    • 共享Cookie和LocalStorage
    • 避免跨域问题
    • 只需要一个域名,配置相对简单
  • 劣势:

    • 耦合度高:应用间存在一定的耦合
    • 扩展性差:难以实现真正的独立部署
    • 技术栈限制:所有应用需要兼容相同的运行环境
      • 由于共享了window对象和全局环境,可能会造成技术栈之间的冲突
      • css样式冲突,同域部署下,所有的应用的css都在同一个文档中,如果类名一样, 容易产生冲突
  • 实现方式:

    • 主应用和子应用部署在同一域名下
    • 通过路径前缀区分不同应用
    • 使用Nginx等反向代理进行路由分发

部署架构​

json
https://example.com/ # 主应用
https://example.com/app1/ # 子应用1
https://example.com/app2/ # 子应用2
https://example.com/app3/ # 子应用3

nginx代理转发配置​

bash
server {
listen 80;
server_name example.com;

# 主应用
location / {
proxy_pass http://main-app:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}

# 子应用1
location /app1/ {
proxy_pass http://app1:3001/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}

# 子应用2
location /app2/ {
proxy_pass http://app2:3002/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}

# 子应用3
location /app3/ {
proxy_pass http://app3:3003/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

跨域部署​

  • 优势:
    • 应用完全独立,隔离性更好
    • 可以独立部署和扩展
    • 支持不同的技术栈和框架
  • 实现方式:
    • 使用postMessage进行跨域通信
    • 通过CORS配置解决跨域问题
    • 使用代理服务器转发请求

部署架构​

js
https://main.example.com/ # 主应用
https://app1.example.com/ # 子应用1
https://app2.example.com/ # 子应用2
https://app3.example.com/ # 子应用3

nginx各应用配置​

bash
# 主应用服务器
server {
listen 80;
server_name main.example.com;
root /var/www/main-app;
index index.html;

location / {
try_files $uri $uri/ /index.html;
}
}

# 子应用1服务器
server {
listen 80;
server_name app1.example.com;
root /var/www/app1;
index index.html;

location / {
try_files $uri $uri/ /index.html;
}

# 允许跨域访问
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
}

子域名部署​

子域名部署通过设置 document.domain 实现同域通信

当两个页面来自同一个主域但子域不同,并且需要绕过同源策略的限制进行通信时,可以通过设置 document.domain 来实现

  • 优势:
    • 介于同域和跨域之间
    • 可以共享部分资源
    • 部署相对简单
  • 实现方式:
    • 主应用:app.example.com
    • 子应用:sub1.app.example.com, sub2.app.example.com
    • 通过document.domain设置共享域名

部署架构​

ts
https://example.com/ # 主应用
https://app1.example.com/ # 子应用1
https://app2.example.com/ # 子应用2
https://app3.example.com/ # 子应用3

document.domain 机制​

js
// 主应用设置
document.domain = 'example.com';

// 子应用设置
document.domain = 'example.com';

// 设置后,主应用和子应用就可以直接通信
// 因为它们的domain都指向了同一个域名

nginx配置​

主域名配置​

bash
# 主应用服务器配置
server {
listen 80;
server_name example.com;
root /var/www/main-app;
index index.html;

location / {
try_files $uri $uri/ /index.html;
}

# 允许跨子域访问
add_header Access-Control-Allow-Origin "https://app1.example.com https://app2.example.com https://app3.example.com";
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE";
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization";
}

子域名配置​

bash
# 子应用1服务器配置
server {
listen 80;
server_name app1.example.com;
root /var/www/app1;
index index.html;

location / {
try_files $uri $uri/ /index.html;
}

# 允许跨子域访问
add_header Access-Control-Allow-Origin "https://example.com https://app2.example.com https://app3.example.com";
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE";
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization";
}

# 子应用2服务器配置
server {
listen 80;
server_name app2.example.com;
root /var/www/app2;
index index.html;

location / {
try_files $uri $uri/ /index.html;
}

# 允许跨子域访问
add_header Access-Control-Allow-Origin "https://example.com https://app1.example.com https://app3.example.com";
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE";
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization";
}