关于iframe:Iframe在Vue中的状态保持技术-京东云技术团队

引言Iframe是一个历史悠久的HTML元素,依据MDN WEB DOCS官网介绍,Iframe定义为HTML内联框架元素,示意嵌套的Browsing Context,它可能将另一个HTML页面嵌入到以后页面中。Iframe能够便宜实现跨利用级的页面共享,并且具备应用简略、高兼容性、内容隔离等长处,因而以Iframe为外围造成了前端平台架构畛域第1代技术。 家喻户晓,当Iframe在DOM中初始渲染时,会主动加载其指向的资源链接Url,并重置外部的状态。在一个典型的平台利用中,一个父利用主页面要挂载多个窗口(每一个窗口对应一个Iframe),那么如何在切换窗口时,实现每一个窗口中的状态(包含输出状态、锚点信息等)不失落,也即“状态放弃”呢? 如果采纳父子利用通信来记录窗口状态,那么革新老本是十分微小的。答案是利用Iframe的CSS Display个性,切换窗口时,非激活状态的窗口并不隐没,仅是Display状态变更为none,激活状态窗口的Display状态变更为非none。在Display状态切换时,Iframe不会从新加载。在Vue利用中,一行v-show指令即可替咱们实现这一需要。 竞争机制上述的状态放弃模型存在一个性能缺点,即父利用主页面实际上要提前摆放多个Iframe窗口。即便是这些不可见的窗口,也会收回资源request申请。大量的并发申请,会导致页面性能降落。(值得一提的是,Chrome最新版本曾经反对了Iframe的滚动懒加载策略,然而在此场景下,并不能改善并发申请的问题。)因而,咱们须要引入资源池和竞争机制来治理多个Iframe。 引入一个容量为N的Iframe资源池来治理多开窗口,当资源池未满时,新激活的窗口能够直接插入至资源池中;当资源池已满时,资源池依照竞争策略,淘汰若干池中的窗口并抛弃,而后插入新激活的窗口至资源池中。通过调整容量N,能够限度父利用主页面上多开窗口的数量,从而限度并发申请数量,实现资源管控的目标。 Vue Patch原理摸索日前遇到了一个基于Vue利用的Iframe状态放弃问题,在上述模型下,资源池不仅保留窗口对象,而且记录了每个窗口的点击激活工夫。资源池应用以下竞争淘汰策略:对窗口激活工夫进行先后秩序排序,激活工夫排序秩序较前的窗口优先被淘汰。当资源池满时,会偶发池中窗口状态不能放弃的问题。 在Vue中,组件是一个可复用的Vue实例,Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。组件状态是否正确放弃,依赖要害属性key。基于此,首先排查了Iframe组件的key属性。事实上,Iframe组件曾经正确调配了惟一的Uid,此种状况能够排除。 既然不是组件复用的问题,那么在Vue外部的Diff Patch机制到底是如何运行的呢?让咱们看一下Vue 2.0的源代码: /** * 页面首次渲染和后续更新的入口地位,也是 patch 的入口地位 */Vue.prototype._update = function (vnode: VNode, hydrating?: boolean) { if (!prevVnode) { // 老 VNode 不存在,示意首次渲染,即初始化页面时走这里 …… } else { // 响应式数据更新时,即更新页面时走这里 vm.$el = vm.__patch__(prevVnode, vnode) }}(1)在update生命周期下,次要执行了vm.__patch__办法。 /** * vm.__patch__ * 1、新节点不存在,老节点存在,调用 destroy,销毁老节点 * 2、如果 oldVnode 是实在元素,则示意首次渲染,创立新节点,并插入 body,而后移除老节点 * 3、如果 oldVnode 不是实在元素,则示意更新阶段,执行 patchVnode */function patch(oldVnode, vnode, hydrating, removeOnly) { …… // 1、新节点不存在,老节点存在,调用 destroy,销毁老节点 if (isUndef(oldVnode)) { …… // 2、老节点不存在,执行创立新节点 } else { // 判断 oldVnode 是否为实在元素 const isRealElement = isDef(oldVnode.nodeType) if (!isRealElement && sameVnode(oldVnode, vnode)) { // 3、不是实在元素,然而老节点和新节点是同一个节点,则是更新阶段,执行 patch 更新节点 patchVnode(oldVnode, vnode, insertedVnodeQueue, null, null, removeOnly) } else { ……// 是实在元素,则示意首次渲染 } } invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch) return vnode.elm}(2)在__patch__办法外部,触发patchVnode办法。 ...

May 25, 2023 · 3 min · jiezi

关于iframe:Iframe标签的传值方式父发给子子接收父的消息-子发给父父接收子的消息

如何进行音讯通信(父发给子,子接管父的音讯; 子发给父,父接管子的音讯)办法一: 间接通过获取父或者子的window来操作 (限度: 必须同域) // 父调用子的办法: this.iframe.contentWindow.iframe的属性办法// 或document.getElementById("myIframe").contentWindow.iframe的属性办法// 子调用父的办法:通过parent间接获取父的windowparent.document...办法二:通过postMessage进行通信(限度: 须要父子约定) // 父监听子音讯:window.addEventListener("message", () => this.listenFunc());// 子发给父音讯: 可通过window的属性找到对应的父(这里的parent示意间接上一级的父)parent.postMessage(data, "*"); // 父给子发消息document.getElementById("iframe").contentWindow.postMessage(JSON.stringify(data), "*")// 子监听父的音讯window.addEventListener("message", () => this.listenFunc());如何找到指定的子或者父window(如果iframe层级过多),又如何在发送音讯时不影响其余的message监听 while(true) { // 判断,找到要找的父window,能够通过在父的window上绑定属性来实现 if(currentWindow.isParent = true) { currentWindow.postMessage(data, "*") } if(currentWindow == window.top) { break; // 避免死循环 } else { currentWindow = currentWindwo.parent; }}origin是否有用event.origin 能够获取以后音讯的起源门路,通过判断以后iframe的url,判断是否是指定页面的消息来源

July 15, 2022 · 1 min · jiezi

关于iframe:iframe-在-SAP-三款产品中的三个应用场景

这是 Jerry 2021 年的第 73 篇文章,也是汪子熙公众号总共第 350 篇原创文章。 iframe 是一项历史悠久的前端技术,可能将另一个 HTML 页面嵌入到以后的宿主页面。每个通过 iframe 被嵌入的 HTML 页面都领有本人独立的浏览上下文,会话历史记录和 DOM 树。尽管 iframe 如果使用不当,可能会引发性能问题和安全隐患,然而它也有其利用场合,即复用第三方利用页面。因而,即使在 SAP 这种企业级应用软件的前端开发畛域,iframe 依然有其一席之地。 本文介绍 Jerry 已经工作过的三款 SAP 产品中 iframe 的应用场景。 SAP CRM WebClient UI - SAP BSP 页面中嵌入 SAP UI5 利用SAP CRM WebClient UI 诞生于本世纪初,底层基于 SAP ABAP BSP(Business Server Page).因为历史起因,WebClient UI 不足对 Chart 类控件的反对。因而,在 SAP CRM WebClient UI 须要实现表现力丰盛的图表展现需要时,应用了 Iframe 嵌入 SAP UI5 图表利用的解决方案。毕竟,利用多种类型的图表出现业务剖析类数据,也是 SAP UI5 利用的强项之一。 应用 SAP CRM 业务角色 Analytics Professional 登录零碎,能够创立 SAP HANA Live Report 这种类型的剖析报表: ...

December 13, 2021 · 3 min · jiezi

关于iframe:iframe实现vue嵌套外部系统

实现目标:内部零碎相干配置放在配置文件中内部零碎渲染入口放在主零碎中,由主零碎router管制内部零碎的加载内部零碎加载过程展现loading相干代码:// config.jsexport default { collect: { staticAddress: 'http://127.0.0.1:9303' }, application: { staticAddress: 'http://127.0.0.1:9304' }};// router.jsimport config from './config.js';import DynamicComponent from './DynamicComponent.vue';{ path: `${baseUrl}/collect`, name: 'collect', props:config.collect, component: DynamicComponent},// DynamicComponent.vue<template> <keep-alive> <iframe ref="dynamicIframe" :src="staticAddress" frameborder="0" style="width:100%;height:100%;" @load="frameLoaded" /> </keep-alive></template><script>export default { name: "DynamicComponent", props: { staticAddress: { type: String, required: true } }, beforeRouteEnter(to, from, next) { next(vm => { // element-ui loading成果 vm.$showViewLoading(); }); }, beforeDestroy() { this.$off('load', this.frameLoaded); }, methods: { frameLoaded() { this.$closeViewLoading(); } }};</script>

March 17, 2021 · 1 min · jiezi

关于iframe:iframe嵌入grafana配置记录

记录一下iframe嵌入grafana1.批改配置文件, conf下default.ini # set to true if you want to allow browsers to render Grafana in a <frame>, <iframe>, <embed> or <object>. default is false.allow_embedding = true改为 allow_embedding = true#################################### Anonymous Auth ######################[auth.anonymous]# enable anonymous accessenabled = true重启 curl -H "Authorization: Bearer eyJrIjoiVUhQSm1yaXVVMDlDRGpzM3FLNVNrZkswa0RMR0ZjaXkiLCJuIjoiYWRtaW4iLCJpZCI6MX0=" http://localhost:3000/api/dashboards/home

March 8, 2021 · 1 min · jiezi

关于iframe:sortablejs-支持-iframe-跨域拖拽

背景最近钻研拖拽生成页面,遇到一个跨iframe拖拽的性能的问题。在此记录下心得。 页面外面的 iframe 在没有跨域的状况下,SortableJS 是反对跨iframe拖拽的,官网仓库给了例子。如果跨域了,咱们拿不到 iframe 的 contentDocument,无奈监听事件,所以 Sortable 默认状况下是不能工作的。 思路 - 模仿拖拽实践上 Sortable 是通过监听事件来实现拖拽的性能,咱们手动结构 drag 事件,告诉 Sortable,也是能够实现工作的。 实际 - 模仿拖拽拖拽须要解决三个事件节点 dragstartdragoverdragenddragstartSortable 一开始不会在 dom 节点加上 draggable 属性,必须点击了才会,所以模仿时,须要先触发一个 pointdown 事件,而后触发 dargstrat 事件 var downEvent = new PointerEvent("pointerdown", { // pointerId: 1, bubbles: true, cancelable: true, // pointerType: "touch", width: 100, height: 100, isPrimary: true,});var startE = new DragEvent("dragstart", { bubbles: true });dragover父页面的 dragover 事件不会传递到 iframe 内(废话),所以咱们只能在 iframe 内监听 mousemove 事件, 而后结构一个 dragover 事件,传递给dom,通知 Sortable 咱们拖动了Sortable元素到该dom下面,看看是不是须要扭转地位。 ...

January 30, 2021 · 1 min · jiezi

关于iframe:iframe相互调用详解

嵌入iframe机制,不可避免的要用到各个iframe页面之间办法和属性的互相调用。 这里设定有3个页面,一个父页面main.html,它嵌入了两个iframe,别离是:childPage1.html和childPage2.html main.html有一个函数叫parentFunc()。main.html代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"><html xmlns="http://www.w3.org/1999/xhtml"> <script type="text/javascript" function parentFunc(){ //代码段 } </script> <body> <IFRAME scrolling="no" frameBorder=0 id=frmchild1 name=frmchild1 height="400" src="childPage1.html" width="100%" allowTransparency="true"></IFRAME> <IFRAME scrolling="no" frameBorder=0 id=frmchild2 name=frmchild2 height="400" src="childPage2.html" width="100%" allowTransparency="true"></IFRAME> </body></html>子页childPage1.html中有函数childFunc1()。代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"><html xmlns="http://www.w3.org/1999/xhtml"> <script type="text/javascript" function childFunc1(){ //代码段 } </script> <body> </body></html>子页childPage2.html中有函数childFunc2()。代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"><html xmlns="http://www.w3.org/1999/xhtml"> <script type="text/javascript" function childFunc2(){ //代码段 } </script> <body> </body></html>子页调父页办法如果子页childPage1.html要调用父页main.html中的parentFunc()办法,那么应该在childPage1.html中写如下代码: parent.parentFunc()或者用 top.parentFunc()parent找上一级,top找最上一级。因为childPage1.html属于二级,所以parent和top作用一样。 如果 childPage1.html又嵌了一个 grandchildrenPage.html的iframe,想要调用main.html中的parentFunc()办法, 则应该 parent.parent.parentFunc()或者用 ...

December 29, 2020 · 1 min · jiezi

关于iframe:iframe嵌套页面以及风险

iframe能够帮忙咱们在一个网页中嵌套另一个网页(比方:jquery我的项目中嵌套react页面),它的用法咱们以理论例子阐明: 在本地写了一个index.html,应用http-server启动服务: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title></head><body> <iframe src="http://47.111.228.207:8080/#/pageA" frameborder="0" width="100%" height="1000" scrolling="no"></iframe></body></html>在index.html中咱们嵌套了一个iframe,指向我之前部署在服务器上的react页面(http://47.111.228.207:8080/#/pageA) 当初浏览器关上http://localhost:8080/ 能够看到曾经胜利的将react页面嵌套进去了。 然而,问题也进去了,http://47.111.228.207:8080/#/pageA这个页面能够被任意的劫持应用,如果被钓鱼网站应用,植入一些小广告或者其余的,那么这些危险都会影响咱们网站的性能以及安全性。 那么,如何去躲避这些危险呢? 常见形式是在apache 或者 tomcat服务器上配置X-Frame-Options响应头 X-Frame-Options是为了缩小点击劫持(Clickjacking)而引入的一个响应头,这个响应头反对三种配置: DENY:不容许被任何页面嵌入;SAMEORIGIN:不容许被本域以外的页面嵌入;ALLOW-FROM uri:不容许被指定的域名以外的页面嵌入(Chrome现阶段不反对);咱们来试试如何在tomcat配置响应头: 参考:https://www.pianshen.com/arti...https://www.cnblogs.com/wdnnc...https://developer.mozilla.org...

November 25, 2020 · 1 min · jiezi