Angular2+ iframe跨域调用父页面js

业务场景:列表页面添加一个导入功能,该导入功能由第三方页面提供,导入完成后需要通知主列表刷新数据。

先来看看iframe跨域调用父页面的实现逻辑(以postMessage方式为例)

(postMessage介绍:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage )

1.父页面html

<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <script type="text/javascript">   window.onload = function () {   //添加监听事件。   if (typeof window.addEventListener != "undefined")     window.addEventListener("message", func, false);   else if (typeof window.attachEvent != 'undefined')//兼容不支持addEventLinstener的IE。     window.attachEvent("onmessage", func); }   //被调用的函数。   function invocationTarget(msg) {     if (msg)       alert(msg);     else       alert("~~~");     }   //监听事件回调函数。   function func(e) {     if (e.data.Result)       invocationTarget(e.data.Data);   } </script> </head> <body>   <iframe src="子页面域名/HtmlPage.html" style="border:0px"></iframe> </body> </html>

2. 子页面html

<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title>   <script type="text/javascript">     function invocation() {       var data = { Result: true, Data: 'hello world' };       //第一个参数表示要传递的参数,第二个参数表示要传递到的目标。       window.parent.postMessage(data, "父页面域名/HtmlPage.html");     }   </script> </head> <body>   <input onclick="invocation();" type="button" /> </body> </html>

以上逻辑是基于父页面是html实现的,见红色字体标注,子页面回调给指定的窗口源。

来看看postMessage参数说明:

postMessage(data,origin)方法接受两个参数

 1.data:要传递的数据,html5规范中提到该参数可以是JavaScript的任意基本类型或可复制的对象,然而并不是所有浏览器都做到了这点儿,部分浏览器只能处理字符串参数,所以我们在传递参数的时候需要使用JSON.stringify()方法对对象参数序列化,在低版本IE中引用json2.js可以实现类似效果。

2.origin:字符串参数,指明目标窗口的源,协议+主机+端口号[+URL],URL会被忽略,所以可以不写,这个参数是为了安全考虑,postMessage()方法只会将message传递给指定窗口,当然如果愿意也可以建参数设置为"*",这样可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。

到此就出现另一个问题了:angular弹窗式组件如何通过URL反映?也就是如何把父页面集成到组件中。

因为组件和js通讯是很好实现的,这样我们可以设法把父页面嵌套在组件中(iframe方式嵌套)

UrlIframeModalComponent组件通过Iframe嵌套IframeModal.html父页面,IframeModal.html父页面通过Iframe嵌套第三方子页面 testurl/

1.UrlIframeModalComponent.html 组件(模态弹出)

<iframe width="100%" height="100%" style="overflow:auto;" frameborder="0" \[src\]=" _/assets/IframeModal.html_ | safe"> </iframe>

UrlIframeModalComponent.ts

export class UrlIframeModalComponent implements OnInit {

constructor() { }

ngOnInit() {

  //添加监听事件:监听由 IframeModal.html发出的callBackFromIframe事件

  document.addEventListener('callBackFromIframe', this.callBack);

}

callBack(evt){

  //回调参数

  const param = evt.param;

  console.log(param);

}

ngOnDestroy() {

  document.removeEventListener("callBackFromIframe", this.callBack); //销毁监听,否则会多次接收

}

}

2._IframeModal.html 父页面,与第三方子页面及UrlIframeModalComponent组件通讯**_
**

<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <script type="text/javascript">   window.onload = function () {   //添加监听事件。   if (typeof window.addEventListener != "undefined")     window.addEventListener("message", func, false);   else if (typeof window.attachEvent != 'undefined') //兼容不支持addEventLinstener的IE。     window.attachEvent("onmessage", func);   }   //被调用的函数。   function invocationTarget(param) {     //接收到子页面消息后,通知组件     var evt = document.createEvent("HTMLEvents");     evt.param = param;     evt.initEvent("callBackFromIframe", false, false);     parent.window.document.dispatchEvent(evt);   }   //监听事件回调函数。   function func(e) {     if (e.data.Result == true)       invocationTarget(e.data); } </script> </head> <body> <iframe src="http://.../第三方子页面.html" style="border:0px"></iframe> </body> </html>

3.第三方子页面

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <link href="css/default.css" type="text/css" rel="stylesheet">

</head> <body>

    <div id="mainDiv">

        <div id="content">

            这是第三方页面功能...

            (导入文件功能)

            <br />

            <br />

            <a style="color:blue; cursor: pointer;" onclick="notifyBack('导入完成')">导入完成</a>

            <a style="color:blue; cursor: pointer;" onclick="notifyBack('取消')">取消</a>

        </div>

    </div>

    <script type="text/javascript">

        function notifyBack(msg) {

            var data = {

                Result: true,

                Data: msg

            };

            //第一个参数表示要传递的参数,第二个参数表示要传递到的目标。

            window.parent.postMessage(data, "http://localhost:4200/assets/IframeModal.html");

        }

    </script>

</body> </html>
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

swap空间的增减方法

(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap

Angular2+ iframe跨域调用父页面js - HelloWorld