先上图:
红框是iFrame嵌入的子页面
之前在《利用iframe嵌入html页面 (实用, 赞)》已试过了iFrame嵌入html,但转到Angular中遇到以下几个问题:
一、利用DomSanitizer, SafeResourceUrl解决xss错误;
参考:
Angular 8 使用 iframe
Angular 2 DomSanitizer
二、用postMessage处理父子相互传值,解决iFrame高度问题;
参考:
postmessage解决iframe跨域嵌套,调用父页面方法【跨页面通信】
iframe和父页面相互传值,并兼容跨域问题.(项目实测成功) from accessing a cross-origin frame
三、解决返回时出现 ‘Cannot GET /null’错误(偶发性),要再点返回才能返回上一页;
原因:
当iframe加载时未准备好src所需的url时,就会出现这种情况;
解问办法:
加上 *ngIf="htmlFileUrl"
【父页面 html】
<meta charset="utf-8" />
<ion-header style="display:none">
<ion-navbar>
<ion-title>
签到有奖
</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<div class="iframe-box">
<!--注意: 必须加上*ngIf="htmlFileUrl", 否则返回上一级有会出'Cannot GET /null' 错误(偶发性)-->
<iframe *ngIf="htmlFileUrl" [src]="htmlFileUrl"
frameborder="0"
allowtrancparency="true"
scrolling="no"
style="border:0px; width: 100%; border: 1px solid red;"
[ngStyle]="getiFrameHeight()"></iframe>
</div>
<div class="footer-bar">
<button ion-button>立即签到</button>
</div>
</ion-content>
【子页面 html】
<head>
<meta charset="utf-8" />
<script>
window.onload = function () {
var doc = window.document;
var body = doc.body;
var html = doc.documentElement;
var height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
window.parent.postMessage(height, '*');
}
</script>
</head>
<img src="http://localhost:3073/htmlfile/MarketAction/9E395AC5-6B64-4B8E-95E6-0ABD46BCB589/202001131729000.jpeg" style="width:100%" />
<P style='font-size: 18px;'>
你好吗!
</P>
<div>
<span style='font-size: 12px; color: orange;'>你猜猜!</span>
<span style="font-size:1.8rem; color: red; font-weight: 800; margin-left: 10px;">错了!</span>>
</div>
【主页面ts】
...
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'
@IonicPage({
name: 'sign-in',
})
@Component({
selector: 'sign-in',
templateUrl: 'sign-in.html'
})
export class SignInPage {
...
private htmlFileUrl: SafeResourceUrl;
private iFrameHeight: number;
constructor(
...
private sanitizer: DomSanitizer
) {
...
}
ngOnInit() {
this.loadData();
window.addEventListener('message', (event) => {
//event.data获取iFrame子页面传过来的数据
this.iFrameHeight = event.data;
});
}
private getiFrameHeight() {
let h = this.iFrameHeight && this.iFrameHeight > 0 ? this.iFrameHeight : 100;
return { 'height': h.toString() + 'px' };
}
private loadData() {
let params = {
...
};
this.appService.callBo("xxx", "xxx", params).subscribe((res) => {
if (res.ErrCode == 0) {
let fileUrl = res.Data.HtmlFileUrl;
this.htmlFileUrl = his.sanitizer.bypassSecurityTrustResourceUrl(fileUrl);
} else {
this.utils.showError(res.ErrMsg);
}
});
}
private submit() {
//
}
}