我有一个主机应用程序和一些微前端应用程序都是 Angular 15。我使用过
"@angular-architects/module-federation": "^15.0.3"
。一切正常,除了我无法拦截加载 mfe 应用程序的 remoteEntry.js 文件的 http 调用。
所有 mfe 应用程序都部署在服务器中,服务器要完成请求,我必须将授权令牌添加到请求中。我尝试了多种方法,但无法拦截调用并将令牌添加到其中。
如有任何建议,我们将不胜感激。
下面是我的路由,我在其中加载mfe
{
path: 'config',
loadChildren: () =>
loadRemoteModule({
remoteEntry: environment.configREmoteEntryURL,
type: "module",
exposedModule: './Module'
})
.then(m => m.AppModule)
},
您可以使用 Service Worker 来拦截和操作所有针对 MFE CDN 的请求。
service-worer.js
let authToken = '';
// This event listeners listens to the requests towards the login
// endpoint and stores that authToken at the corresponding variable.
self.addEventListener('fetch', function (event) {
if (event.request.url === 'https://auth-endpoint/login') {
event.respondWith(
fetch(event.request)
.then(function (response) {
var responseClone = response.clone();
responseClone.json().then(function (data) {
authToken = data.token;
});
return response;
})
);
}
});
// This requests listens to the requests towards the MFEs' endpoint
// and adds the custom headers needed fot the authorization
self.addEventListener('fetch', function (event) {
if (event.request.url.startsWith('https://remotes-endpoint/')) {
let url = new URL(event.request.url);
let headers = new Headers(event.request.headers);
headers.set('Content-Type', 'application/javascript');
headers.set('Authorization', authToken);
let newRequest = new Request(url, {
method: event.request.method,
headers,
mode: 'cors',
credentials: 'same-origin',
redirect: event.request.redirect
});
event.respondWith(fetch(newRequest));
}
});
您需要在 bootstrap.js 中注册您的 Service Worker
...
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register('/service-worker.js')
.then(function (registration) {
console.log('Service Worker registration successful with scope: ', registration.scope);
}, function (err) {
console.log('Service Worker registration failed: ', err);
});
});
}
在您的 webpack 配置中添加 CopyPlugin
const CopyPlugin = require('copy-webpack-plugin');
const config = {
...
plugins: [
...
new CopyPlugin({
patterns: [
// adjust 'service-worker.js' if your file is somewhere else
{ from: 'service-worker.js', to: '' },
],
}),
]
}
module.exports = config;
您很可能还需要从模块联合配置中删除遥控器,只要在用户登录之前消费者应用程序的挂载上不存在 authToken。因此,遥控器的请求将在挂载时失败。要解决此问题,您需要使用动态远程容器加载遥控器。此repo中完整实现了此方法。
恐怕目前这是不可能的。
您的用例是什么?
这个解决方案很聪明,但它对我来说不起作用,我会改变一些东西。
mode:'cors',凭据:'same-origin',-这意味着服务器正在对remoteEntry文件使用某种授权+它应该支持cors请求。因此,这样编写会在启动真正的请求之前创建一个选项请求,这在您的服务器上可能是不允许的。实际上,常见的 GET 请求(没有自定义标头)不应该要求打开 CORS。因此,只需省略凭据,并将模式更改为:
mode: "no-cors"
发送的缓存控制标头对我来说不起作用,但您可以做一个简单的增强: 让 url = 新 URL(event.request.url);
网址=
${url}?${Date.now()}
;
第二步将保证您获得文件的新副本,在每个请求上添加此随机散列,这将防止 proweser 缓存它。