Angular2 - 成功获取iframe.contentWindow并调用postMessage()时出错

时间:2016-11-23 12:47:36

标签: node.js angular iframe postmessage

我有一个Angular 2项目和一个NodeJs项目。我在Angular 2应用程序中有一个iframe,我想在其中显示NodeJS应用程序。我想使用从Angular2到NodeJs的postMessage()方法,然后反向(从NodeJs到Angular2)。 Angular2地址为http://localhost:3001,NodeJs地址为http://localhost:3005

在Angular 2中,我有一个像这样的组件模板;

template: `<iframe id="ifrm" #ifrm [src]="iframeURL()" width="500" height="200"> <p> Your browser does not support iframes</p> </iframe> `

<小时/> 模板中使用的iframeURL()方法体;

iframeURL() {
 return this.sanitizer.bypassSecurityTrustResourceUrl('http://localhost:3005');
}

<小时/> 当我运行应用程序时,我可以在Angular2中的iframe中看到该页面。但是当我想获得iframe的contentWindow(下面的代码)时,我得到下面的解释(不是错误);

@ViewChild('ifrm') iframe: ElementRef;
  

异常:DOMException:使用origin阻止了一个框架   &#34; http://localhost:3001&#34;从访问跨源框架。

<小时/> 当我使用如下的postMessage()方法时,我得到了异常;

this.iframe.nativeElement.contentWindow.postMessage('{}','http://localhost:3005');
  

无法执行&#39; postMessage&#39;在&#39; DOMWindow&#39;:目标来源   提供(&#39; http://localhost:3005&#39;)与收件人不匹配   窗口的起源(&#39; http://localhost:3001&#39;)。

<小时/> 顺便说一下,我使用角度路由打开这个组件页面。 整个组件代码如下:

import {Component, OnInit, ElementRef} from '@angular/core';
import {DomSanitizer} from '@angular/platform-browser'
import {ViewChild} from "@angular/core/src/metadata/di";

@Component({
    selector: 'app',
    template: `<div> <iframe id="ifrm" #ifrm [src]="iframeURL()" width="500" height="200" style="/*display:none;*/"> <p> Your browser does not support iframes</p> </iframe> </div>`
})
export class AppComponent implements OnInit{
    constructor(private sanitizer: DomSanitizer){}

    @ViewChild('ifrm') iframe: ElementRef;

    ngOnInit(){
        console.log(this.iframe.nativeElement.contentWindow);
        this.iframe.nativeElement.contentWindow.postMessage('{}', 'http://localhost:3005');
    }

    iframeURL() {
        return this.sanitizer.bypassSecurityTrustResourceUrl('http://localhost:3005');
    }
}

2 个答案:

答案 0 :(得分:4)

这就是我处理问题的方法。仅在========================== |OrganismName|Month|Cases| ========================== |nota |2 |2 | |something |4 |0 | |something |10 |1 | |woo |2 |1 | |woo |7 |0 | ========================== 之后postMessage。虽然它可能对您不起作用,但您可以尝试一下:

ngAfterViewInit
<iframe #iframe class="iframe-map" (load)="onIframeLoad()"></iframe>

答案 1 :(得分:0)

为了简化代码,可以使用Angular的Renderer2,还可以使用标记名称代替ElementRef来获取iframe元素。

import { Component, Renderer2, AfterViewInit } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';

@Component({
  selector: 'app-root',
  template: `<iframe [src]="iframeURL" #iframeTagName (load)="loadIframe(iframeTagName)" style="visibility: hidden; position: absolute; left: 0; top: 0; height:0; width:0; border: none;"><iframe>`
})
export class AppComponent implements AfterViewInit {
  iframeURL;
  private isInited;

  constructor(
    private domSanitizer: DomSanitizer,
    private renderer: Renderer2
  ) {
    this.iframeURL= this.domSanitizer.bypassSecurityTrustResourceUrl('http://iframe-url.com');
  }

  loadIframe(iframeTagName) {
    if (this.isInited) {

      // post message to iframe
      iframeTagName.contentWindow.postMessage('message' , 'http://iframe-url.com');

      // You can receive response from iframe if any
      this.renderer.listen('window', 'message', (event) => {

        if (event.origin !== 'http://iframe-url.com') {
          return;
        }

        // handle event here

     });
   }

   ngAfterViewInit() {
      this.isInited = true;
   }
}