大家好呀,我是前端创可贴。
上一章我们学习了关于 HTML 中视频的相关内容,相信大家对于现在的视频平台有了更多的认知。
这一章我们再一起来学习一下大名鼎鼎的 iframe。
iframe(The Inline Frame element)
iframe 元素表示一个嵌套的浏览上下文,它的内容可以是一个外部页面(通过 src
属性加载)或嵌入的 HTML(通过 srcdoc
属性定义)。
通过 iframe 我们可以非常方便的嵌入别的网页,不管是同源还是非同源,并且还可以限制它的行为和权限,以保证网页的安全。
我们可以将含有 iframe 元素的文档称为父文档(或者说父浏览上下文),iframe 元素渲染出来的文档称为子文档(或者说子浏览上下文)。
src 属性
通过 src 属性可以指定 iframe 要加载的页面的 URL。
必须是一个有效且非空的 URL,可以包含空格(首尾的空格会被忽略)。
<iframe src="https://example.com"></iframe>
复制
与父文档同源的 iframe,在父文档可以读取到子文档的 DOM 和完整属性的 Window 对象等。
contentWindow
iframe 元素的 contentWindow 属性,返回 iframe 元素渲染的文档的 Window 对象。
- 如果子文档与父文档是同源的,则该属性返回值的对象功能是不受限的,含有其全部属性以及访问 DOM 的权限。
- 如果是跨域的,则返回的 Window 对象功能是受限的,很多属性以及访问 DOM 权限都是没有的。
对于含有 srcdoc 属性的 iframe 来说,没有设置 sandbox 的情况下,它与父文档永远是同源的。
同源 iframe 的 contentWindow 属性:
非同源 iframe 的 contentWindow 属性:
contentDocument
iframe 元素的 contentDocument 属性,返回 iframe 元素渲染的文档的 Document 对象。
- 如果子文档与父文档是同源的,则该属性返回代表 iframe 元素的 Document 对象。
- 如果是跨域的,则返回 null。
同源 iframe 的 contentDocument 属性:
非同源 iframe 的 contentDocument 属性:
parent
window 对象的 parent 属性,返回父文档的 Window 对象。
如果当前文档是最顶层,没有父文档,则 window.parent
返回当前文档的 window 对象。通常用于在 iframe 元素的文档中获取父文档的 window 对象。
- 如果子文档与父文档是同源的,则该属性返回值的对象功能是不受限的,含有其全部属性以及访问 DOM 的权限。
- 如果是跨域的,则返回的 Window 对象功能是受限的,很多属性以及访问 DOM 权限都是没有的。
当子文档与父文档是同源的时候,我们就可以通过 window.parent
与父文档通信,具体见后面的小节。
判断当前浏览上下文是否是 iframe,可以通过判断 parent === window
,如果为 true,则说明不是 iframe;否则说明是 iframe。
<h1>前端创可贴</h1> <iframe srcdoc="<div>我是 iframe</div> <script>console.log('iframe 内执行 parent === window 结果:', parent === window)</script> " frameborder="0" ></iframe> <script> console.log("父文档执行 parent === window 结果:", parent === window); </script>
复制
srcdoc 属性
通过 srcdoc 属性,可以直接为 iframe 指定其嵌入页面的内容,而不是通过 URL 加载。
赋值 srcdoc 属性,会生成一个特殊的文档,URL 为 about:srcdoc
。
赋值的属性值必须要符合 HTML 语法,包含以下组成部分:
- 任意数量的注释和 ASCII 空白字符(如空格、换行)。
- 可选的 DOCTYPE 声明。
- 任意数量的注释和 ASCII 空白字符。
- 必须包含 html 元素作为文档的根。
- 任意数量的注释和 ASCII 空白字符。
<iframe srcdoc=" <!DOCTYPE html> <html> <head> <title>Embedded Document</title> </head> <body> <h1>Hello from srcdoc!</h1> </body> </html> "></iframe>
复制
转义
由于 srcdoc 属性在 iframe 元素中是用 "
包裹的,而 srcdoc 属性值为 HTML 代码,也可能含有 "
,所以属性值里的 "
必须先转义为 "
,否则会导致 srcdoc 属性提前结束。或者使用单引号来代替双引号。
<iframe srcdoc="<p title="Example">Hello, world!</p>"></iframe> <iframe srcdoc="<p title='Example'>Hello, world!</p>"></iframe>
复制
文档结构简化
虽然 srcdoc 属性值是一段 HTML 代码,但并不必须是完整的 HTML 代码,对于 srcdoc 属性来说很多元素是可选的,没有存在的必要:
DOCTYPE
声明是可选的。html
、head
和body
标签的起始与结束标记是可选的。title
元素也是可选的。
由于许多元素是隐式存在的,所以其实只需要显式编写 body
元素里面的内容就可以了,所以 srcdoc
属性值可以非常简洁。
<iframe srcdoc="<div>前端创可贴</div>"></iframe>
复制
src 和 srcdoc 属性同时存在
如果同时指定了 src
和 srcdoc
属性,srcdoc
属性优先级更高,浏览器会忽略 src 属性,加载并显示 srcdoc
中的嵌入内容。
src
属性会作为回退兜底,如果浏览器不支持 srcdoc
属性(例如旧版本浏览器),会加载 src
指定的 URL 作为回退内容。
<iframe src="https://example.com/fallback.html" srcdoc="<div>前端创可贴</div>" sandbox> </iframe>
复制
消耗资源
由于每一个 iframe 都是一个完整的 document 环境,也就是一个浏览上下文,所以每一个 iframe 都需要用到一些内存和计算资源,如果页面嵌套的 iframe 元素太多,可能会出现性能问题。
我们来验证一下,我们页面放两个按钮,一个按钮点击后新增一个 iframe 元素,另外一个按钮新增 div 元素:
<h1>前端创可贴</h1> <button id="btn1">创建 div</button> <button id="btn2">创建 iframe</button> <script> let num = 1; btn1.addEventListener("click", () => { const div = document.createElement("div"); div.innerHTML = `我是 div${num++}`; document.body.append(div); }); btn2.addEventListener("click", () => { const iframe = document.createElement("iframe"); iframe.srcdoc = `我是 iframe${num++}`; document.body.append(iframe); }); </script>
复制
我们打开浏览器的 Performance monitor
工具,看一下他们对 CPU 和内存的影响。
我们先来看看创建很多 div 元素对 CPU 和内存的影响:
可以看到,对 CPU 和内存几乎没什么影响。我们换成 iframe 再看一下:
可以看到,对 CPU 和内存的消耗还是比较明显的,我这里演示的 iframe 里的内容还特别少,更何况是复杂的页面,所以大家可以减少页面内嵌套 iframe 的使用,以减少内存,这对于移动端来说颇为重要。
延迟主文档的 load 事件
嵌套的 iframe 元素加载了一个子文档,子文档中的资源、脚本等的加载会延迟子文档自己的 load 事件,也会延迟主文档的 load 事件。子文档的 load 事件先触发,然后触发父文档的 load 事件。
<!-- 父文档 --> <h1>前端创可贴</h1> <iframe src="./child.html" frameborder="0"></iframe> <script> window.addEventListener("load", () => { console.log("父文档 load 事件"); }); </script>
复制
<!-- 子文档 --> <div>我是 iframe</div> <script> window.addEventListener("load", () => { console.log("子文档 load 事件"); }); </script>
复制
主文档加载完成后,开始解析和加载 iframe
内容。结果是子文档的 load 事件先触发,然后触发父文档的 load 事件:
loading 属性
iframe 的子文档会延迟父文档的 load 事件,这是因为 iframe 的加载默认是同步的,我们可以通过 loading
属性设置为异步。
loading
是一个懒加载属性,用于定义在视口之外的 iframe
元素的加载策略。其主要目的是通过延迟加载不在视口范围内的 iframe,提高页面性能和资源利用效率。
loading 属性只对 src 属性有效,对 srcdoc 属性是无效的。
它的值可以是:
lazy
(懒加载)
表示只有当 iframe 接近或进入视口时才开始加载。就算 iframe 一开始就在视口范围内,它仍然是懒加载的,父文档的 load 事件会先执行,iframe load 事件后执行。
eager
(即时加载)
默认值,表示 iframe 应立即加载,无论是否在视口范围内。
仍然使用上面的例子,在父文档的 iframe 元素加上 loading 属性:
<iframe src="child.html" loading="lazy"></iframe>
复制
可以看到,父文档的 load 事件先执行了,子文档不再延迟父文档的 load 事件。
使用 loading="lazy"
时,浏览器会推迟 iframe 的网络请求和渲染,直到其即将进入视口。这可能会减少带宽占用,但也可能导致用户在快速滚动时看到加载延迟。所以对于关键内容建议不要懒加载,或者自定义控制加载时机。
sandbox 属性
通过 sandbox
属性可以对嵌入内容施加额外的安全限制,允许开发者逐步放宽某些默认的沙箱限制。它是强化安全的关键机制,用于隔离潜在的不可信内容。
设置 sandbox
属性后,嵌入内容会被视为来自一个不透明源(opaque origin),嵌入内容被隔离,无法共享任何同源信息。可使用 allow-same-origin
解除此限制,使内容被视为来自其实际来源。
它的值可以是(可以组合):
allow-same-origin
:允许内容与其来源共享相同的安全上下文(即不跨域沙箱化)。否则即使它与宿主页面同源,内容仍会被限制为跨域环境(说人话,就是因为 sandbox 属性会创建一个不透明源,使用该属性可以解除不透明源)。该属性使内容被视为来自其实际的 origin。如果没有设置该值,iframe 无法访问 cookie、web storage 等。
allow-downloads
:允许嵌入的内容触发下载操作(例如<a download>
)。默认情况下,沙箱环境会阻止下载。由于通过 a 元素的 download 属性下载文件,要求下载的文件必须与触发下载的页面同源,所以还必须给 iframe 加上 allow-same-origin,让子文档变成其实际的 origin,才能下载成功。
allow-forms
:允许提交表单。默认情况下,表单提交被禁用。
allow-modals
:允许使用模态对话框(如alert()
、prompt()
和confirm()
)。默认情况下,模态对话框被禁用。
allow-orientation-lock
:允许内容锁定设备的屏幕方向。
allow-pointer-lock
:允许内容锁定指针(如使用pointerlock
API)。默认情况下,指针锁定被禁用。
allow-popups
:允许弹出窗口(如window.open()
)。默认情况下,弹出窗口被阻止。
allow-popups-to-escape-sandbox
:允许弹出的窗口跳过沙箱限制。必须配合allow-popups
使用。默认情况下,iframe 嵌入内容打开的新窗口,仍会受 sandbox 影响。
allow-presentation
:允许内容启动演示模式,例如通过Presentation API
。
allow-scripts
:允许脚本执行,但不允许创建新的弹出窗口(除非同时使用allow-popups
)。默认情况下,脚本被禁用。
allow-top-navigation
:允许 iframe 内容触发顶层导航(即替换宿主页面)例如,window.top.location = "https://baidu.com
可生效。默认情况下,顶层导航被禁用。
allow-top-navigation-by-user-activation
:仅允许通过用户操作(如点击链接或按钮)触发顶层导航。
allow-top-navigation-to-custom-protocols
:允许嵌入内容导航到自定义协议(如mailto:
、tel:
)。要小心使用,避免潜在安全风险。
当指定 sandbox
属性但未设置任何值时,所有的限制均启用(完全沙箱化)。需要放宽某些限制,就必须显式添加相应的值。
但是大家注意⚠️,滥用放宽限制可能导致安全风险,应在满足最小权限原则的前提下使用。
allow-scripts 与 allow-same-origin 同时存在
当 allow-scripts
与 allow-same-origin
同时存在时,并且嵌入的页面与包含 iframe 的页面同源,嵌入的页面就可以突破沙盒限制:
- 嵌入的页面可以通过脚本操作
window.parent.document
或通过window.frameElement
获取自身的 iframe 元素,直接移除 sandbox 属性。
- 一旦
sandbox
属性被移除,嵌入页面重新加载后,沙盒限制将不再生效。
父文档:
<h1>前端创可贴</h1> <iframe src="child.html" sandbox="allow-scripts allow-same-origin"> </iframe>
复制
子文档:
<div>我是 iframe</div> <script> (() => { // 获取窗口嵌入的元素 const iframeElement = window.frameElement; if (!iframeElement.hasAttribute("sandbox")) { return; } // 移除 iframe 的 sandbox 属性 iframeElement.removeAttribute("sandbox"); // 重新加载页面 window.location.reload(); })(); </script>
复制
iframe 嵌入内容不再受沙盒限制,sandbox 属性被删除了。
sandbox 会影响 iframe 内新打开的 tab
sandbox 属性管的非常宽,它不仅会影响 iframe 文档,甚至还会影响 iframe 内通过 window.open 打开的新窗口。
例如 iframe 打开一个新 tab,新 tab 执行 alert 方法,如果顶层的 iframe 的 sandbox 属性没有设置 allow-modal,新 tab 执行 alert 就会失败。
通过设置 sandbox 属性值为 allow-popups-to-escape-sandbox
,可以让新窗口不受 sandbox 影响。
移除 sandbox 属性
sandbox
属性中的限制和权限仅在 iframe
元素的内容导航(即加载新的内容)时生效。
如果 iframe
已经加载了某个页面,动态移除或修改 sandbox
属性并不会改变当前已加载内容的权限,当前页面仍受加载时的 sandbox 限制约束。
要使移除 sandbox
生效,必须重新加载 iframe
内容,例如重新赋值 src
(即使赋值为原来的值,iframe 也会重新加载)。
// 重新导航 iframe,使修改的 sandbox 属性生效 iframe.removeAttribute('sandbox'); iframe.src = 'xxx';
复制
新加载的内容不再受 sandbox
限制,因为加载时 sandbox
属性已被移除。
什么场景下会出现删除 sandbox 属性的情况呢?比如默认情况下加载内容时启用 sandbox
,用以确保内容在加载时受到限制,在经过安全性评估后,可以通过移除 sandbox
属性并重新加载内容,为新加载的页面解除限制。
但是大家注意⚠️,这种动态操作可能导致复杂的安全问题,并使行为难以预测,所以建议大家尽量不要动态操作 sandbox 属性,可能会出现意料之外的安全风险,并且难以维护。
allow 属性
allow
属性用于定义一个 权限策略(Permissions Policy),其主要作用是为 iframe 内嵌内容指定某些 Web 平台特性的可用性,更加精细化地增强安全性和功能控制。
我们先来看看什么是权限策略。
权限策略(Permissions Policy)
与 allow 属性的作用相同,事实上 allow 属性是应用权限策略的方式之一。用于精细化地控制 Web 功能,限制功能是否可用并且限制哪些指定的 origin 可用。
权限策略和内容安全策略(Content Security Policy,CSP)比较像,他们的写法比较相似,只是权限策略不是控制安全行为相关,而是控制一些精细化的 Web 功能,例如定位、摄像头、麦克风等。
权限策略以前被叫做功能策略(Feature Policy),如果大家见到叫做这个名字的 HTTP 响应头,它们的作用是一样的。
权限策略,有两种启用方式:
- 通过 HTTP 响应头
Permissions-Policy
设置,影响当前文档及其内部所有 iframe 文档。
- 通过 iframe 元素的
allow
属性设置,只影响当前 iframe 文档。
继承
如果上述两种启用方式同时都设置了,对于当前文档来说只会应用响应头的限制;而对于 iframe 元素来说,会结合两者,使用最大程度的限制,iframe 要使用的 Web 功能必须同时满足 Permissions-Policy 响应头以及 allow 属性的 origin 限制。
同样的,如果父 iframe 和子 iframe 都设置了 allow 属性,子 iframe 也会结合两者,使用最大程度的限制。
如果 Permissions-Policy 响应头或者父 iframe 的 allow 属性禁用了某个功能,所有的子级 iframe 都无法开启这个功能,包括所有后代的 iframe(孙子、重孙子等)。
权限策略(permissions policy)所支持的值,包含 功能名称 和 允许来源。
功能名称
常见的功能有:
autoplay
:允许媒体自动播放。camera
:允许使用摄像头。document-domain
:允许设置 document.domain 的值。fullscreen
:允许使用全屏 API 进行全屏。geolocation
:允许使用定位 API。microphone
:允许使用麦克风。picture-in-picture
:允许视频以画中画的形式播放。- ...
允许来源
指定功能可以应用在哪些 origin,值包含在括号里,用空格隔开。
它的值可以是:
*
:任意 origin 都可以使用功能。()
(空来源):任意 origin 都禁用使用功能。self
:只有同源才可以使用功能。如果嵌入的 iframe 地址与当前文档非同源,则无法使用功能。'src'
:只有和当前 iframe 的 src 属性同源,才可以使用功能。该值只能用在 iframe 的 allow 属性,也是其允许来源的默认值,也就是说例如<iframe allow="geolocation">
等同于<iframe allow="geolocation 'src'">
。"<origin>"
:只有指定的域名才可以使用功能,可以指定多个域名,用空格隔开。可以使用通配符*
。如果用在 iframe 元素的 allow 属性,则要去掉引号。
例如:
*
()
(self)
(src)
(self "https://a.example.com" "https://b.example.com"
("https://*.example.com")
Permissions-Policy 响应头的格式为:Permissions-Policy: <directive>=<allowlist>
用法
介绍完了权限策略,看看如何通过 allow 属性来启用权限策略。
对于 iframe 来说,allow 属性中的功能需要同时满足父文档的限制,所以如果父文档的 HTTP 响应头中指定了功能范围,iframe allow 属性必须是功能范围的子集。
allow
属性值的格式如下:
<iframe allow="权限名称1 'self'; 权限名称2 'none'; 权限名称3 https://example.com"></iframe>
复制
例如给 iframe 设置只有跟当前文档以及指定 origin 同源时才能使用功能:
<iframe src="https://example.com" allow="geolocation 'self' https://a.example.com https://b.example.com; fullscreen 'none'"></iframe>
复制
如果当前的 iframe 并没有用到别的 origin,但是含有链接可以跳转到别的 origin,跳转后的页面仍然在 allow 属性的管辖范围内,所以如果不在 allow 属性中指定别的 origin,当跳转后就会出现功能不可用的问题。
referrerpolicy 属性
用于控制访问 iframe 资源时的 referrer 请求头。
它的值可以是:
no-referrer
:完全不发送Referer
请求头。no-referrer-when-downgrade
:当目标页面使用 HTTPS 时,发送完整的 Referer;如果从 HTTPS 访问 HTTP,则不发送 Referer。origin
:仅发送来源页面的 协议、主机名和端口号,也就是只发送源 origin,不包含路径或查询参数。origin-when-cross-origin
:同源请求发送完整的 URL 作为Referer
;跨域请求仅发送源 origin。same-origin
:同源请求发送完整的Referer
;跨域请求不发送任何Referer
。strict-origin
:当协议安全级别一致(如 HTTPS → HTTPS)时,仅发送源 origin。当从 HTTPS 访问 HTTP 时,不发送Referer
。strict-origin-when-cross-origin
:
-
- 同源请求:发送完整的 URL。
- 跨域请求(协议安全级别一致,如 HTTPS → HTTPS):仅发送源 origin。
- 跨域请求(从 HTTPS 到 HTTP):不发送
Referer
。
unsafe-url
:发送完整的 URL。
通信
父文档与子文档有时需要进行通信,例如子文档渲染完成后调用父文档的函数。
父子文档通信有 3 种方式:
- 同源时,通过 contentWindow 与 window.parent 访问对方的 Window 对象。
- 非同源时,通过 postMessage 方式。
- 非同源时,通过 postMessage + MessageChannel 方式。
方式一:通过 parent 方式通信。
<!-- 父文档 --> <h1>前端创可贴</h1> <iframe src="./child.html" frameborder="0"></iframe> <script> window.customData = "你好我是前端创可贴"; </script>
复制
<!-- 子文档 --> <div>我是 iframe</div> <script> console.log("通过 parent 从父文档获取的数据:", parent.customData); </script>
复制
方式二:通过 postMessage 方式通信。
<!-- 父文档 --> <h1>前端创可贴</h1> <button id="btn">发送数据</button> <iframe id="iframe" src="./child.html" frameborder="0"></iframe> <script> btn.addEventListener("click", () => { iframe.contentWindow.postMessage("你好我是前端创可贴", "*"); }); </script>
复制
<!-- 子文档 --> <div>我是 iframe</div> <script> addEventListener("message", (e) => { console.log("通过 postMessage 从父文档获取的数据:", e.data); }); </script>
复制
方式三:通过 postMessage + MessageChannel 方式通信。
<!-- 父文档 --> <h1>前端创可贴</h1> <button id="btn">发送数据</button> <iframe id="iframe" src="./child.html" frameborder="0"></iframe> <script> const p = new MessageChannel(); btn.addEventListener("click", () => { iframe.contentWindow.postMessage("", "*", [p.port2]); setTimeout(() => { p.port1.postMessage("你好我是前端创可贴"); }); }); </script>
复制
<!-- 子文档 --> <div>我是 iframe</div> <script> addEventListener("message", (e) => { const port = e.ports[0]; port.onmessage = (e) => { console.log("通过 messageChannel 从父文档获取的数据:", e.data); }; }); </script>
复制
iframe 内的页面跳转
iframe 里的文档可以进行页面的跳转,会在顶层文档中留下历史记录,也就是可以点击浏览器的后退和前进。iframe 里的页面跳转(包括点击浏览器的前进后退按钮)不会影响顶层页面的 URL,也不会影响 iframe 之外的元素。
大家可以看到,在 iframe 里产生页面跳转,并不会影响外层元素以及 url。如果 iframe 页面跳转以后再刷新页面:
可以看到,iframe 内的状态丢失了,在 url 上也没有任何改变,这也就是为什么大家不用 iframe 实现微前端的原因之一。
其实也可以实现让页面 url 一起变化,但是需要一些额外编码,并且耦合性有点高。
一起来简单实现一下,当 iframe 内进行页面跳转时,影响顶层文档的 url。
拦截子文档内的所有 a 元素跳转,点击 a 元素会向父文档通过 postMessage 发送 a 元素要跳转的路径,父文档通过 message 事件获取到路径后通过 history.pushState
修改 url。并且页面刷新时,父文档将当前 url 中的路径同样通过 postMessage 发送给子文档,子文档获取到后修改子文档的 href,展示跳转后的页面。
parent 页面:
<body> <h1>前端创可贴 parent</h1> <iframe id="iframe" src="child.html" frameborder="0" ></iframe> </body> <script> window.addEventListener("message", (event) => { if (event.origin !== "http://127.0.0.1:5500") return; // 获取 iframe 的路径 const iframePath = event.data.path; // 更新父页面的 URL(不重新加载页面) history.pushState(null, "", iframePath); }); // 父页面加载时,解析 URL 并初始化 iframe 状态 window.addEventListener("load", () => { const currentPath = window.location.pathname; // 初次加载时不发送路径给子文档 if (currentPath === "/turbo/apps/iframe/parent.html") { return; } // 将当前父页面 URL 的路径传递给 iframe iframe.contentWindow.postMessage({ path: currentPath }, "*"); }); </script>
复制
child 页面:
<body> <h1>child</h1> <a href="./child2.html">跳转</a> </body> <script> const updateParentUrl = (path) => { window.parent.postMessage({ path }, "*"); // 向父页面发送路径信息 }; // 模拟内容切换 const links = document.querySelectorAll("a"); links.forEach((link) => { link.addEventListener("click", (event) => { event.preventDefault(); // 阻止默认跳转 const newPath = event.target.getAttribute("href"); // 修改当前子文档内容 location.href = newPath; // 通知父页面更新 URL updateParentUrl(newPath); }); }); // 监听来自父页面的消息,更新 iframe 状态 window.addEventListener("message", (event) => { if (event.origin !== "http://127.0.0.1:5500") return; const { path } = event.data; location.href = path; }); </script>
复制
通过这种方式可以实现 url 的同步,不丢失 iframe 状态。但是还存在很多问题,例如:
- 耦合性很高,子文档无法脱离父文档单独运行,违背了微前端独立部署的特性(直接宣判死刑);
- 我们是通过父文档的 history.pushState 实现的 url 变化,由于 history API 的特性,点击浏览器的前进后退按钮,页面是不会刷新的,我们还需要监听 popstate 事件继续做额外的工作。
- 我们通过父文档的 pushState 增加了一个历史记录,而子文档修改了 location.href 也会增加一个历史记录,导致一次链接跳转出现了 2 个历史记录。如果使用 replaceState 代替,就会出现页面返回时无法再复原原来的 url。
- 我们确实修改了 url,对于单页面项目来说,刷新页面不会有问题,一定会由父文档将路径传给子文档;而如果是多页面项目,此时 url 是一个子文档中的真实 url,刷新后只会展示子文档而丢失了父文档的展示。
- ...
可以看到,问题还有很多,所以 iframe 实现微前端是有很多问题的,这里我们只介绍了 url 不同步的问题,限于篇幅已经很长,以后有机会再跟大家细聊 iframe 实现微前端的优缺点。
结束语
这一章我们学习了 iframe 的相关内容,掌握了 iframe 的用法,包括 src、srcdoc、loading 属性、sandbox 属性、allow 属性等,全方面的学习了如何更好的使用和控制 iframe,保障嵌入的内容不会影响外层内容的安全。
最后还扩充了一下 iframe 内部跳转链接,介绍了为何业界普遍不采用 iframe 作为微前端解决方案的原因之一,碍于篇幅原因没有再介绍 iframe 实现微前端的优缺点,以后有时间再跟大家细说。
那么这一章的介绍就结束了,咱们下一章再见啦。
欢迎关注我的公众号,前端创可贴。