Angular 2 iframe与父通信

时间:2017-01-16 10:53:54

标签: javascript angular iframe

在我目前的项目中,我有多个Angular 2应用程序,应该由门户应用程序(也是Angular 2)提供服务。因此,门户网站应用程序的标题区域包含指向所有底层应用程序的链当用户点击一个应用程序链接时,相应的角度2应用程序将加载到门户网站主体的iframe中。

enter image description here

现在我开发了一个中央授权服务。在门户网站中,我有一个服务,它拥有当前登录用户的权限。我的问题是:是否可以在单个应用程序(iframe)中访问父(门户)的角度2服务/组件?它似乎可能是角1 via scope

2 个答案:

答案 0 :(得分:9)

我正在考虑做类似的事情(在iFrame中使用子应用程序的门户应用程序) 您可以使用 window.postMessage 发送数据,在服务器和客户端之间进行通信(向任一方向)。

例如,在服务器应用程序上:

var iframe = document.getElementById('useriframe');
    if (iframe == null) return;
    var iWindow = (<HTMLIFrameElement>iframe).contentWindow;

    iWindow.postMessage({"for":"user","data":"anything"}, 'http://localhost:4001');

并在客户端应用上(在iFrame中托管)

export class AppComponent {

@HostListener('window:message',['$event'])
onMessage(e)
{
if (e.origin!="http://localhost:4200")
  {
  return false;
  }
if (e.data.for=="user")
  {
  alert('here i am');
  }
}

在父级中显示子框架路径 因此,在我的实现中,我们将shell应用程序中的标记和用户信息传递给子iFrame,我们将子应用程序的路由信息​​传递回shell,以便url反映子应用程序中选择的路由。 在子应用程序中,您可能有以下路线:

  

[userapp] / edituser /用户名

,我们希望将其发布到父应用程序并显示如下路径:

  

http://mywebsite/main/application/user#edituser/bob

请注意,我们使用hashtag标记子路由,并在您的子应用程序中拦截每个导航事件并通过

发布新路由
export class MyRoutingComponent implements OnInit {
constructor(private router: Router) { 
router.events.subscribe((event: Event)=>{
  if (event instanceof NavigationEnd){
        let url=(<NavigationEnd>event).url;
        if (url.length>1)//don't post message about base route '/'
          window.parent.postMessage({"for":"dashboard", "operation":"changeroute","route":url},'*')
  }

})
}

然后在父应用程序中解析消息并使用它来更新显示的位置路径。

    url = url +'#' + route;            
    this.location.go(url);

答案 1 :(得分:4)

非常感谢@ jazza1000提供的解决方案,它帮助了我。

我们的问题是在当前(迄今为止)版本的angular cli中有一个bug,即使使用allowJs也会阻止使用外部JS文件。我们将使用jsplumb(外部js)来表示一些流程图。 (Actual issue on stack overflow

所以我们决定采用在另外的角度4应用程序中托管使用​​外部JS的功能的方法。并且父角5应用程序将引入带有iFrame的角度4应用程序。因此,当用户想要查看流程图时,我们将在iframe中打开angular4应用程序,然后一旦完成,他将在角度4应用程序中单击保存,这将保存他的所有修改,然后将消息发送到将关闭/隐藏的父窗口iframe的div。

我们在angular 5中的父应用程序有代码

 @HostListener('window:message', ['$event'])
  onMessage(e) {
    debugger;
    if (e.origin != "http://localhost:4201") {
      return false;
    }
    if (e.data.for == "user") {
      alert('here i am');
    }
  }

我们在保存按钮上的iFrame angular 4应用程序有代码(我们用--port 4201启动应用程序)

window.parent.window.postMessage({"for":"user","data":"anything"}, 'http://localhost:4200')