Angular2 - 问题获取 iframe.contentWindow 成功和错误调用 postMessage()

bar*_*maz 1 iframe postmessage node.js angular

我有一个 Angular 2 项目和一个 NodeJs 项目。我在 Angular 2 应用程序中有一个 iframe,我想在其中显示 NodeJS 应用程序。我想使用 postMessage() 方法从 Angular2 到 NodeJs,然后反向(从 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> `
Run Code Online (Sandbox Code Playgroud)


模板中使用的 iframeURL() 方法体;

iframeURL() {
 return this.sanitizer.bypassSecurityTrustResourceUrl('http://localhost:3005');
}
Run Code Online (Sandbox Code Playgroud)


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

@ViewChild('ifrm') iframe: ElementRef;
Run Code Online (Sandbox Code Playgroud)

异常:DOMException:阻止了一个带有“ http://localhost:3001 ”的框架访问跨源框架。


当我使用如下所示的 postMessage() 方法时,出现异常;

this.iframe.nativeElement.contentWindow.postMessage('{}','http://localhost:3005');
Run Code Online (Sandbox Code Playgroud)

无法在“DOMWindow”上执行“postMessage”:提供的目标源(“ http://localhost:3005 ”)与收件人窗口的源(“ http://localhost:3001 ”)不匹配。


顺便说一下,我正在使用角度路由打开这个组件页面。整个组件代码如下:

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');
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 5

这就是我处理问题的方式。只有postMessagengAfterViewInit. 虽然它可能不适合你,但你可以试试:

<iframe #iframe class="iframe-map" (load)="onIframeLoad()"></iframe>
Run Code Online (Sandbox Code Playgroud)
<iframe #iframe class="iframe-map" (load)="onIframeLoad()"></iframe>
Run Code Online (Sandbox Code Playgroud)