当前位置: 首页 > news >正文

iframe通过postMessage进行跨域通信以及在Angular中使用

写在前面

在前端开发过程中,会遇到一些需要使用iframe的场景,使用iframe关键的一个点是数据之间的传输,基于同源的要求十分苛刻,大家基本上是都是跨域的,如果跨域进行数据传输呢?
大家使用的比较多的就是postMessage()这个方法了,下面将具体展示如何在html中使用iframe进行数据传输,以及在angular框架中如何使用以及在angular中与html中的差异性

普通html页面

由外到内(向iframe内网页传输数据)

使用iframe处

<body><iframe src="./iframe-content.html" class="iframe" frameborder="0"></iframe><script>const iframeElement = document.querySelector(".iframe");//需要等待iframe加载完成后再发送信息,原因是 iframe的网页需要注册message事件,若先发消息再注册,那么在注册之前是收不到消息的iframeElement.addEventListener("load", () => {//相当于iframe自己给自己发消息iframeElement.contentWindow.postMessage("这是一条信息", "*");});</script></body>

iframe内容

<body><span>这里是iframe内容</span><script>window.addEventListener("message", (event) => {console.log(event.data);});</script>
</body>

由内到外

使用iframe处

  <body><iframe src="./iframe-content.html" class="iframe" frameborder="0"></iframe><script>window.addEventListener("message", (event) => {console.log(event.data);});</script></body>

iframe内容

 <body><span>这里是iframe内容</span><script>//给上层级发消息,若上层级是顶层可以使用window.topwindow.parent.postMessage("给使用处发消息", "*");</script></body>

在Angular使用

  • 首先是src 在angular中直接使用src链接会被认为是不安全的,需要通过DomSanitizer中的bypassSecurityTrustResourceUrl方法进行一个转化才可使用
constructor(private sanitizer: DomSanitizer
) {this.src = this.sanitizer.bypassSecurityTrustResourceUrl(`${path}`);
}
  • 其次是在获取iframe 可以通过 @ViewChild来获取
@ViewChild('iframe') iframeElement:ElementRef<HTMLIFrameElement>; 来进行获取
  • 通过监听iframe load事件来判断接受事件是否注册不能使用了 ,就需要在iframe内部传来一条信息来通知事件是否注册完成
  iframeElement.addEventListener("load", () => {iframeElement.contentWindow.postMessage("这是一条信息", "*");});
  window.parent.postMessage(true); //通知app事件注册成功//接受iframe来的通知 基于rxjs去写事件的监听fromEvent<MessageEvent>(window, 'message').pipe(map(data => data.data)).pipe(takeUntil(this.ngUnsubscribe$)).subscribe(isLoaded => {if (isLoaded) {this.templatePreviewIframe.nativeElement.contentWindow.postMessage(数据);}});

总结

html

<iframe
#iframe
[src]="src"
frameborder="0"
></iframe>
src:string;
ngUnsubscribe$= new Subject();
@ViewChild('iframe') iframeElement: ElementRef<HTMLIFrameElement>;
constructor(private sanitizer: DomSanitizer
) {this.src = this.sanitizer.bypassSecurityTrustResourceUrl(`${path}`);
}ngOnInit(){fromEvent<MessageEvent>(window, 'message').pipe(map(data => data.data)).pipe(takeUntil(this.ngUnsubscribe$)).subscribe(isLoaded => {if (isLoaded) {this.templatePreviewIframe.nativeElement.contentWindow.postMessage(数据);}});
}ngOnDestroy(){this.ngUnsubscribe$.next();this.ngUnsubscribe$.complete();
}

iframe内容网页

ngOnInit(){fromEvent(window, 'message').subscribe((event: MessageEvent<any>) => {//todo});window.parent.postMessage(true); //通知app事件注册成功
}
http://www.lryc.cn/news/146816.html

相关文章:

  • rust学习-引用C库
  • WebAssembly 在云原生中的实践指南
  • Azure sqlserver 更改字符集
  • git push时,由于commit了大文件无法成功push的解决办法
  • 2023_Spark_实验一:Windows中基础环境安装
  • 如何在Windows / Mac / iPhone / Android / Online上将MP4转换为MP3
  • 【App端】uni-app使用百度地图api和echarts省市地图下钻
  • 深度学习(十)--- cv2.pointPolygonTest() 判断一点是否在指定区域内
  • 后端面试话术集锦第 八 篇:redis面试话术
  • LiteOS qemu realview-pbx-a9 环境搭建与运行
  • Kubernetes技术--Kubernetes架构组件以及核心概念
  • 拿来即用修改密码功能
  • 违背原则才能写好代码(一)
  • 面试官眼中的理想候选人:如何成为他们的首选
  • ES6中的扩展运算符你真的会用吗?
  • 利用逻辑回归判断病人肺部是否发生病变
  • 全民健康生活方式行动日,天猫健康联合三诺生物推出“15天持续测糖计划”
  • 设计模式行为型-状态模式
  • 弹窗、抽屉、页面跳转区别 | web交互入门
  • 说说Flink运行模式
  • 视频汇聚/视频云存储/视频监控管理平台EasyCVR新增首次登录强制修改密码
  • C语言控制语句——分支语句
  • 音视频 fmpeg命令裁剪和合并视频
  • 机器学习基础17-基于波士顿房价(Boston House Price)数据集训练模型的整个过程讲解
  • 哈希的应用——布隆过滤器
  • LNMT的多机部署和双机热备
  • 软件测试/测试开发丨Pytest和Allure报告 学习笔记
  • 十七、命令模式
  • 服务器安装 anaconda 及 conda: command not found [解决方案]
  • 自动驾驶和辅助驾驶系统的概念性架构(二)