当 iframe 在 Angular 中加载时立即发送 postmessage() 到 iframe

问题描述 投票:0回答:1

我有一个系统,其中集成 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 秒。

javascript angular iframe
1个回答
0
投票
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

试试这个..

© www.soinside.com 2019 - 2024. All rights reserved.