You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Module Federation的Angular微前端部署时出现CORS错误

问题:Docker部署Angular微前端后出现CORS错误

本地开发时,Angular 14宿主应用与两个微前端运行正常,但容器化部署到Docker后,宿主容器请求微前端的remoteEntry.js时触发CORS错误:

Access to script at 'http://localhost:3000/remoteEntry.js' from origin 'http://localhost:5000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.


微前端webpack.config.js

const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const mf = require("@angular-architects/module-federation/webpack");
const path = require("path");
const share = mf.share;

const sharedMappings = new mf.SharedMappings();
sharedMappings.register(
  path.join(__dirname, '../../tsconfig.json'),
  [
    '@shared'
  ]);

module.exports = {
  devServer: {
    allowedHosts: 'all',
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
      "Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
    }
  },
  output: {
    uniqueName: "medicalcoding",
    publicPath: "auto"
  },
  optimization: {
    runtimeChunk: false
  },
  resolve: {
    alias: {
      ...sharedMappings.getAliases(),
    }
  },
  experiments: {
    outputModule: true
  },
  plugins: [
    new ModuleFederationPlugin({
      library: { type: "module" },
      name: "medicalcoding",
      filename: "remoteEntry.js",
      exposes: {
        './Module': './projects/medicalcoding/src/app/app.module.ts',
      },
      shared: share({
        "@angular/core": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
        "@angular/common": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
        "@angular/common/http": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
        "@angular/router": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
        ...sharedMappings.getDescriptors()
      })
    })
    , sharedMappings.getPlugin()
  ],
};

宿主应用webpack.config.js

const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const mf = require("@angular-architects/module-federation/webpack");
const path = require("path");
const share = mf.share;

const sharedMappings = new mf.SharedMappings();
sharedMappings.register(
  path.join(__dirname, '../../tsconfig.json'),
  [
    '@shared'
  ]);

module.exports = {
  output: {
    uniqueName: "mainapp",
    publicPath: "auto",
    scriptType: 'text/javascript'
  },
  optimization: {
    runtimeChunk: false
  },
  resolve: {
    alias: {
      ...sharedMappings.getAliases(),
    }
  },
  experiments: {
    outputModule: true
  },
  plugins: [
    new ModuleFederationPlugin({
      library: { type: "module" },
      remotes: {
        "medicalcoding": "http://localhost:3000/remoteEntry.js",
        "paymentposting": "http://localhost:4000/remoteEntry.js"
      },
      shared: share({
        "@angular/core": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
        "@angular/common": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
        "@angular/common/http": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
        "@angular/router": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
        ...sharedMappings.getDescriptors()
      })
    }),
    sharedMappings.getPlugin()
  ],
};

解决方案

1. 明确webpack devServer配置的适用范围

你在微前端webpack.config.js中配置的devServer.headers仅对本地开发阶段的webpack-dev-server生效,Docker部署时用的是生产构建后的静态文件,这部分配置不会被加载,所以需要在生产环境的静态资源服务器中单独配置CORS。

2. 在Docker容器的静态服务器中添加CORS头

如果用Nginx托管微前端静态文件,修改Nginx配置文件:

server {
    listen 80;
    root /usr/share/nginx/html;

    # 添加CORS响应头
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,PATCH,OPTIONS;
    add_header Access-Control-Allow-Headers X-Requested-With,content-type,Authorization;

    # 处理OPTIONS预检请求
    if ($request_method = OPTIONS) {
        return 204;
    }

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

将该配置文件复制到Docker镜像的Nginx配置目录(如/etc/nginx/conf.d/default.conf)即可。

3. 统一域名路径(生产环境最优方案)

跨域问题本质是域名/端口不一致,更优雅的解决方式是用反向代理(Nginx/Traefik等)将所有应用映射到同一个域名的不同路径下:

  • 宿主应用:http://your-domain.com/main
  • medicalcoding微前端:http://your-domain.com/medicalcoding
  • paymentposting微前端:http://your-domain.com/paymentposting

然后修改宿主应用的webpack.config.js中的remotes配置为相对路径:

remotes: {
  "medicalcoding": "/medicalcoding/remoteEntry.js",
  "paymentposting": "/paymentposting/remoteEntry.js"
}

微前端的publicPath保持auto即可自动适配路径,彻底避免跨域问题。

4. 其他静态服务器的CORS配置

如果用Node.js的serve包托管静态文件,启动时添加CORS参数:

serve -s dist/medicalcoding --cors

如果用自定义Express服务器,直接在中间件中设置响应头:

const express = require('express');
const app = express();

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,PATCH,OPTIONS');
  res.header('Access-Control-Allow-Headers', 'X-Requested-With,content-type,Authorization');
  next();
});

app.use(express.static('dist/medicalcoding'));
app.listen(3000);

内容的提问来源于stack exchange,提问作者Alphonse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 19:03:02