使用Module Federation实现MFE时遭遇CORS错误求助
问题描述
尝试通过Module Federation实现微前端,操作流程如下:
- 执行命令
ng add @angular-architects/module-federation@16 --project remoteapplazy2 --port 5002添加模块联邦库 - 宿主应用配置远程入口为
http://localhost:5002/remoteEntry.js
本地用 ng serve 同时运行宿主和远程应用时一切正常,但将远程应用通过 ng build 构建后,用Node.js服务器部署时出现两种错误:
- 服务器运行在8091端口时:
GET http://localhost:5002/remoteEntry.js net::ERR_CONNECTION_REFUSED main.ts:5 Error loading remote entries TypeError: Failed to fetch dynamically imported module: http://localhost:5002/remoteEntry.js - 服务器改为5002端口运行时,出现CORS错误:
Access to script at 'http://localhost:5002/remoteEntry.js' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. main.js:1 GET http://localhost:5002/remoteEntry.js net::ERR_FAILED 200 (OK)
已在5002端口的Node.js服务器中配置CORS:
app.use(function(req, res, next) { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST'); res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization'); next(); });
额外测试:创建本地HTML文件加载 http://localhost:5002/remoteEntry.js,无CORS错误。
问题分析与解决方案
1. 核心差异:ng serve vs 自定义部署
ng serve 运行时,@angular-architects/module-federation会自动处理跨域逻辑(内部代理或注入CORS头),但构建后部署到自定义Node服务器时,需要手动配置跨域规则。
本地HTML文件无CORS错误的原因:本地HTML以 file:// 协议打开,浏览器对跨域script标签的限制远低于HTTP站点(http://localhost:4200),因此不会触发严格的CORS检查。
2. 修复CORS配置
首先打开浏览器DevTools的Network面板,查看 remoteEntry.js 请求的Response Headers,确认是否存在 Access-Control-Allow-Origin: *。如果没有,按以下步骤调整:
调整中间件顺序:CORS中间件必须放在静态资源路由之前,否则静态文件请求不会经过CORS处理:
// 先配置CORS规则 app.use(function(req, res, next) { res.setHeader('Access-Control-Allow-Origin', '*'); // 加上OPTIONS方法,浏览器会先发预检请求验证权限 res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization'); // 直接响应OPTIONS请求,避免预检失败 if (req.method === 'OPTIONS') { return res.sendStatus(200); } next(); }); // 再挂载构建后的静态目录 app.use(express.static('dist/remoteapplazy2'));验证服务器路径:确认Node.js服务器正确指向远程应用的
dist目录,确保remoteEntry.js能被正常访问。
3. 替代方案:用反向代理避免CORS
如果不想处理CORS,可以在宿主应用侧配置反向代理,将跨域请求转发到远程服务器:
在宿主应用根目录创建
proxy.conf.json:{ "/remoteEntry.js": { "target": "http://localhost:5002", "secure": false, "changeOrigin": true }, // 代理远程应用的所有静态资源(chunk文件等) "/remoteapplazy2": { "target": "http://localhost:5002", "secure": false, "changeOrigin": true } }修改宿主应用的
webpack.config.js中的远程配置,将绝对路径改为相对路径:remotes: { remoteapplazy2: "remoteapplazy2@/remoteEntry.js" }启动宿主应用时指定代理配置:
ng serve --proxy-config proxy.conf.json
4. 同域名部署(彻底避免跨域)
将宿主和远程应用部署在同一个域名下,比如:
- 宿主应用:
http://localhost:4200/ - 远程应用:
http://localhost:4200/remote/
修改远程应用的 angular.json 中的 baseHref 为 /remote/,构建后将dist目录放在宿主服务器的 remote 子目录下,这样所有请求都在同域名下,不会触发CORS。
内容的提问来源于stack exchange,提问作者Subham

