关于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

从零开始搭建前端监控系统三实现控制iframe前进后退

前言本系列文章旨在讲解如何从零开始搭建前端监控系统。 项目已经开源 项目地址: https://github.com/bombayjs/b... (web sdk)https://github.com/bombayjs/b... (服务端,用于提供api)(未完)https://github.com/bombayjs/b... (后台管理系统,可视化数据等)(未完)您的支持是我们不断前进的动力。 喜欢请start!!! 喜欢请start!!! 喜欢请start!!! 本文是该系列第三篇,重点讲解如何控制iframe的前进后退。 系列文章: 从零开始搭建前端监控系统(一)——web探针sdk从零开始搭建前端监控系统(二)——实现圈选(无埋点)k示例https://abc-club.github.io/de... 演示 源码https://github.com/abc-club/demo 如果想看跟复杂的例子,可以看bombayjs的源码 后台截图如下: 难点document.getElementById('iframe id').contentWindow.history.back();以上面这种方式控制会存在跨域问题!!! 原理解决iframe的跨域问题,我们需要通过postMessage实现iframe的通信通过window.history.back()和window.history.forward()控制前进后退实现index.html<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title></head><body> <div> <iframe id='iframe'></iframe> <br/> url: <span id='url'></span> <br/> <button id='back' onclick='back()'>back</button> <button id='forward' onclick='forward()'>forward</button></div> <script> var url = './iframe.html' var div = document.getElementById('url'), iframe = document.getElementById('iframe') iframe.src = url div.innerHTML = url window.addEventListener('message', function(event) { if (!event.data.url) return div.innerHTML = event.data.url; }, false) function back() { iframe.contentWindow.postMessage('back', '*'); } function forward() { iframe.contentWindow.postMessage('forward', '*'); } </script></body></html>iframe.html<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title></head><body> <div> <a href='#a'>to #a</a> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p id='a'>a</p> <p>2</p> <p>2</p> <p>2</p> <p>2</p> <p>2</p> <p>2</p> <p>2</p> <p>2</p></div> <script> window.addEventListener('message', function(event) { if (event.data === 'back') { window.history.back() } else { window.history.forward() } }, false) window.addEventListener('hashchange', function(event) { window.parent.postMessage({ url: location.href }, '*') return }, false) </script></body></html>更多资源https://github.com/abc-club/f... ...

October 8, 2019 · 1 min · jiezi

在-HTML-中包含资源的新思路

作者:scott jehl翻译:疯狂的技术宅 原文:https://www.filamentgroup.com... 未经许可严禁转载 注意:这篇文章描述了一种我们仍需要测其试性能影响的实验技术。 它可能最终会成为一种有用的工具,也有可能成为不被推荐的做法。 无论哪种方式,它对我们来说很有吸引力! 只要我一直工作在 Web 上,就需要一种简单的 HTML 驱动方式,将另一个文件的内容直接包含在页面中。 例如,我经常希望向页面添加额外的 HTML,或者嵌入 SVG 文件的内容,以便我们可以为其设置动画和样式。 通常我们通过使用 JavaScript 获取文件并将其内容附加到特定元素,或者通过在服务器端去包含文件来实现这种嵌入,但在大多数情况下,这些方法都不是我们想要的。 本周我在思考如何用一些新的与 fetch 相关的标记模式来实现这一点,例如 rel="preload" 或 HTML import,但我总是得出的相同结论,即这些都不能使你方便地访问所取得的文件的内容。 然后我想,假设浏览器允许我在父文档中检索 iframe 的内容,也许一个旧的 iframe 可能是一个很不错的模式。 事实证明,它肯定会的! 一个短小的演示:包含 SVG下面是一个内联(嵌入式)SVG 图形。它是从外部文件 signal.svg中加载的。 要加载并嵌入 SVG 文件,我用了下面的标记: <iframe src="signal.svg" onload="this.before((this.contentDocument.body || this.contentDocument).children[0]);this.remove()"></iframe>尽管此标记以 iframe 开头,但如果你使用开发人员工具检查上面的图形,将会看到 SVG 的图标标记,就内嵌在 HTML DOM 中,而且找不到 iframe 元素。 这是因为代码用 iframe 加载文件,并且在删除 iframe之前,用 onload 事件在 HTML 中 iframe 的位置之前注入了 iframe 里的内容。 该方法也适用于 object 元素,无论如何它通常用于引用SVG,所以我认为这特别好。 对于一个object,src 属性必须用 data 替代: ...

September 20, 2019 · 2 min · jiezi

学习htmliframe

基本概念iframe 作为html页面构成的基本元素之一,具备下面的特点 行内元素,默认宽度300px,高度150px遵循流式布局(Flow content),位于body元素内段落内容(Phrasing content),可以构成一个段落嵌入资源(Embedded content),类似的还有video、img等可交互(Interactive content),类似的还有button、textarea等无子节点(Palpable content),iframe标签内部不嵌入任何元素,相反,div标签内就可以嵌入其他元素关于html元素的构成的内容划分,这张图有一个很好的解释: 基本用法iframe具备一些节点属性,如下: src:资源的地址 绝对地址: 会加载对应地址的资源相对地址: 会加载当前页面,默认同源about:blank: 会显示一个空白页srcdoc: iframe中需要render的内容,会覆盖掉对应的资源的内容为什么要这么做?在iframe中,你可以加载不同的内容,这类内容不会被浏览器再一次进行解释,举个例子来说:如果你想嵌入一些特别的符号,你就可以和sandbox联合使用(例子中的amp就是一个特殊符号)<iframe sandbox srcdoc="<p>hey that's earl's table. <p>you should get earl&amp;amp;me on the next cover." ></iframe>name:给嵌入的文档资源起的一个名字sandbox:设置一些安全规则,规定了嵌入资源的一些行为,是否允许弹窗的行为 allow-forms, allow-modals, allow-orientation-lock, allow-pointer-lock, allow-popups, allow-popups-to-escape-sandbox, allow-presentation, allow-same-origin, allow-scripts, allow-top-navigation, and allow-top-navigation-by-user-activation.allowfullScreen: 规定嵌入资源是否允许全屏,true为允许比如你嵌入了一篇文章,这篇文章有全屏观看的操作<iframe src="http://article...."></iframe>// http://article....<div id='article' onclick={handleFullClick}>// 省略文章内容</div>script:const handleFullClick = () => { const article = document.getElementById('article'); article.requestFullscreen();}allow,设置是否允许对应的特征策略// 嵌入的iframe是否允许定位<iframe src="https://maps.example.com/" allow="geolocation"></iframe>referrerpolicy:是以枚举类型,设置了一些策略enum ReferrerPolicy { "", "no-referrer", "no-referrer-when-downgrade", "same-origin", "origin", "strict-origin", "origin-when-cross-origin", "strict-origin-when-cross-origin", "unsafe-url"};contentDocument和contentWindow:返回的是iframe对应的document和window与当前页面的document和window对应。ok,总结起来就是,iframe可以嵌入第三方资源,并且可以对第三方资源进行策略限制,为了安全,毕竟第三方,需要一定的兜底处理。 ...

May 26, 2019 · 1 min · jiezi