2016-11-23 1 views
0

У меня есть проект Angular 2 и проект NodeJs. У меня есть iframe в приложении Angular 2, и я хочу показать приложение NodeJS. Я хотел бы использовать метод postMessage() от Angular2 до NodeJs, а затем наоборот (от NodeJs до Angular2). Адрес Angular2: http://localhost:3001 и адрес NodeJs: http://localhost:3005.Angular2 - Проблема с получением iframe.contentWindow успешно и ошибка при вызове postMessage()

In 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. Но когда я хочу получить contentWindow iframe (код ниже), я получаю объяснение ниже (не ошибка);

@ViewChild('ifrm') iframe: ElementRef; 

Исключение: DOMException: Blocked кадр с происхождения "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

Это, как я справиться с этой проблемой. только postMessage последующий ngAfterViewInit. Хотя это может не работать для вас, вы можете попробовать:

<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

Смежные вопросы