2016-11-23 507 views
0

我有一個Angular 2項目和一個NodeJs項目。我在Angular 2應用程序中有一個iframe,我想在其中顯示NodeJS應用程序。我想使用從Angular2到NodeJs的postMessage()方法,然後反轉(從NodeJs到Angular2)。 Angular2地址是http://localhost:3001,NodeJs地址是http://localhost:3005Angular2 - 問題獲取iframe.contentWindow成功和錯誤調用postMessage()

在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'); 
} 


當我運行應用程序,我可以看到的iframe頁面中Angular2。但是,當我想要獲取iframe的contentWindow(代碼如下)時,我會得到下面的解釋(不是錯誤);

@ViewChild('ifrm') iframe: ElementRef; 

異常:拋出:DOMException:訪問一個跨來源幀阻止與原籍 「http://localhost:3001」 的幀。


當我使用像下面的postMessage()方法時,我得到異常;

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

無法執行 '的postMessage' 上 'DOMWindow':提供的目標來源 ( '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'); 
    } 
} 
+0

任何幫助,將不勝感激。 –

回答

2

這是我如何處理這個問題。在ngAfterViewInit之後只有postMessage。雖然它可能不適合你的工作,你可以嘗試:

<iframe #iframe class="iframe-map" (load)="onIframeLoad()"></iframe> 
import { Component, AfterViewInit, ChangeDetectionStrategy, ViewChild, ElementRef, Inject, Optional, Renderer } from '@angular/core'; 
import { URLSearchParams } from '@angular/http'; 
import { DialogRef, ModalComponent } from 'angular2-modal'; 
import { BSModalContext } from 'angular2-modal/plugins/bootstrap'; 
import { stringify } from 'querystringify'; 

import { AmapPickerOptions, AmapLocation, AMAP_PICKER_OPTIONS, AMAP_KEY, stringify as amapstringify } from '../amap'; 

export class AmapPickerModalData extends BSModalContext { 
    public center: string; 
} 

@Component({ 
    selector: 'amap-picker-modal', 
    templateUrl: './modal.component.html', 
    styleUrls: ['./modal.component.css'], 
    changeDetection: ChangeDetectionStrategy.OnPush, 
}) 
export class AmapPickerModalComponent implements ModalComponent<AmapPickerModalData>, AfterViewInit { 

    @ViewChild('iframe') iframe: ElementRef; 

    receiveMessage: EventListener; 

    private isInited: boolean; 

    constructor(
    @Inject(AMAP_KEY) private key: string, 
    @Optional() @Inject(AMAP_PICKER_OPTIONS) private options: AmapPickerOptions, 
    private renderer: Renderer, 
    public dialog: DialogRef<AmapPickerModalData>) { } 

    ngOnInit() { 
    let center = this.dialog.context.center; 
    this.options = Object.assign({ key: this.key }, this.options, center && { center }); 
    let query = stringify(this.options, true); 
    this.renderer.setElementProperty(this.iframe.nativeElement, 'src', `https://m.amap.com/picker/${query}`) 

    this.receiveMessage = (event: MessageEvent) => { 
     if (event.origin !== 'https://m.amap.com') { 
     return; 
     } 
     this.dialog.close(amapstringify(<AmapLocation>event.data)); 
    }; 
    } 

     ngAfterViewInit() { 
     this.isInited = true; 
     } 

    ngOnDestroy() { 
    window.removeEventListener('message', this.receiveMessage); 
    } 

    onIframeLoad() { 
    if (this.isInited) { 
     setTimeout(() => { 
     this.iframe.nativeElement.contentWindow.postMessage('hello', 'https://m.amap.com/picker/'); 
     window.addEventListener('message', this.receiveMessage, false); 
     }, 500); 
    } 
    } 

} 
+0

你是我的英雄!這很好用! – irhetoric