我有一个系统,其中集成 iframe 的外部项目是 Angular 的,iframe 代码也是 Angular 的。 iframe 具有某些查询参数,例如登录 ID、密码,这些参数会在 iframe 加载时立即读取,并且工作正常。 A 必须发送另一组也需要立即读取的数据,我遇到了 postmessage() 并使用了它。
外部项目代码:
<iframe #challanFlowIframe
src="http://url/query?username=&password="
style="height: 600px; width: 1000px;"
frameborder="50"
(load)="validateAdminRole()"
>
</iframe>
validateAdminRole(){
const iframeWindow = this.challanFlowIframe.nativeElement.contentWindow;
iframeWindow.postMessage('ADMIN', '*');
}
validateAdminRole() 函数编写在 html 模板所在的同一组件内。
iframe代码:
在 iframe 项目的 main.ts 中我尝试读取数据,这是一个独立的组件项目
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
import { UtilService } from './app/shared/util.service'
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
window.addEventListener('message', (event) => {
if (event.data) {
let utilService = new UtilService()
utilService.saveRoleOfCaller(event.data)
}
})
我发现,尽管代码写在 main.ts 中,但构造函数和 ngOnInit() 在此函数之前运行以读取消息。在 ngOnInit() 内部,存在读取查询参数的代码,同样我也想读取使用 postmessage() 发送的角色
通过这种方式我制作了独立的应用程序
ngDoBootstrap() {
const element = createCustomElement(GenerateChallanDetailsComponent, {
injector: this.injector,
});
customElements.define('app-generate-challan-details', element);
}
使用:Angular 17
问题是为什么 postmessage() 需要花费 2-3 秒的时间来读取消息。有没有更好的方法(如果不是解决方案)可以立即获得该角色。
感谢您的帮助,我希望能够解释问题。
我阅读了 MDN 和一些媒体上的帖子,尝试使用纯 JavaScript 监听来自组件generatechallan(来自构造函数、ngOnInit() 和类外的事件)的消息,以找到读取消息所需的时间)但没有发现任何重大变化。阅读它仍然需要大约 2-3 秒。
import { APP_INITIALIZER, Injector, Provider } from '@angular/core';
export const iframeListenerProvider: Provider[] = [
{
provide: APP_INITIALIZER,
useFactory: iframeListenerFactory,
multi: true,
deps: [Injector],
},
];
function iframeListenerFactory(injector: Injector): () => Promise<void> {
return () => {
return new Promise<void>((resolve, reject) => {
try {
if (typeof window !== 'undefined') {
window.addEventListener('message', (event) => {
if (event.data) {
console.log(event.data);
window.parent.postMessage('gotcha -> ' + event.data, '*');
}
});
}
resolve();
} catch (error) {
reject(error);
}
});
};
}
https://v17.angular.io/api/core/APP_INITIALIZER
试试这个..