不同宿主Angular应用(ng4与ng5)iframe通信方案咨询
Hey there! I’ve tackled cross-app iframe communication between different Angular versions before, so I can walk you through the most reliable approaches to set up a channel between your ng4 and ng5 apps:
postMessage API (Most Universal & Secure) This browser-native API is the go-to solution for iframe communication—it works for both same-domain and cross-domain scenarios, and plays nicely with any Angular version. Here's how to implement it:
Sending messages from ng4 (parent app) to ng5 (iframe app)
First, get a reference to your iframe and send messages once it’s fully loaded:
// In your ng4 component import { Component, ViewChild, ElementRef } from '@angular/core'; @Component({ selector: 'app-ng4-parent', template: `<iframe #ng5Iframe src="https://your-ng5-app-url.com" (load)="onIframeLoaded()"></iframe>` }) export class Ng4ParentComponent { @ViewChild('ng5Iframe') ng5Iframe: ElementRef; onIframeLoaded() { // Send structured data to the ng5 app this.ng5Iframe.nativeElement.contentWindow.postMessage( { type: 'USER_AUTH', payload: { userId: 123, token: 'xyz-789' } }, 'https://your-ng5-app-url.com' // Replace with your ng5 app's actual domain; use '*' only for local testing ); } }
Receiving messages in ng5 (iframe app)
Add an event listener to the window object to catch incoming messages, and always verify the sender’s origin to prevent security risks:
// In your ng5 component import { Component, OnInit, OnDestroy } from '@angular/core'; @Component({ selector: 'app-ng5-child', template: `<div>Ng5 App Content</div>` }) export class Ng5ChildComponent implements OnInit, OnDestroy { ngOnInit() { window.addEventListener('message', this.handleNg4Messages.bind(this)); } handleNg4Messages(event: MessageEvent) { // Validate the sender to avoid malicious messages if (event.origin !== 'https://your-ng4-app-url.com') return; switch(event.data.type) { case 'USER_AUTH': console.log('Received auth data from ng4:', event.data.payload); // Send a reply back to ng4 if needed event.source.postMessage( { type: 'AUTH_CONFIRMED', payload: { status: 'success' } }, event.origin ); break; // Add more cases for different message types } } ngOnDestroy() { // Clean up the event listener to prevent memory leaks window.removeEventListener('message', this.handleNg4Messages.bind(this)); } }
Key Notes:
- Always specify the exact
targetOrigininstead of using*in production—it’s critical for security. - Structure your messages with a
typefield to easily distinguish between different communication scenarios.
If both apps are hosted on the same domain, you can use global window variables to share data. This is simpler but less flexible than postMessage, and carries a risk of variable name collisions.
ng4 Parent App:
onIframeLoaded() { // Attach data to the window object (window as any).ng4SharedData = { theme: 'dark', locale: 'en-US' }; // Trigger a custom event to notify ng5 the data is ready this.ng5Iframe.nativeElement.contentWindow.dispatchEvent(new CustomEvent('ng4DataReady')); }
ng5 Iframe App:
ngOnInit() { window.addEventListener('ng4DataReady', () => { const sharedData = (window as any).ng4SharedData; console.log('Shared data from ng4:', sharedData); }); }
For larger apps, wrap the postMessage logic in a reusable Angular service to keep your components clean. Here’s a quick example for ng4:
// ng4 app: iframe-communication.service.ts import { Injectable } from '@angular/core'; @Injectable() export class IframeCommunicationService { private iframe: HTMLIFrameElement; setIframeReference(iframe: HTMLIFrameElement) { this.iframe = iframe; } sendMessage(type: string, payload: any, targetOrigin: string) { if (this.iframe) { this.iframe.contentWindow.postMessage({ type, payload }, targetOrigin); } } }
Then inject this service into your ng4 component to send messages, and create a similar service in ng5 to handle incoming messages.
内容的提问来源于stack exchange,提问作者Prashant Sahu

