基本概念
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;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 可以嵌入第三方资源,并且可以对第三方资源进行策略限制,为了安全,毕竟第三方,需要一定的兜底处理。
常用的业务场景
与 iframe 之间的通信
iframe 是被浏览器的当前页面以第三方资源的形式嵌入的,如果想二者之间实现通信,就需要通过 postMessage
otherWindow.postMessage(message, targetOrigin, [transfer]);
- otherWindow: 窗口的引用,也就是你要向谁发送消息
- message:发送消息的内容,会被结构化克隆算法序列化
- targetOrigin:指定哪些窗口可以没收到消息
- transfer:transfer 中的对象,发送之后,就会被垃圾回收,不存储任何内容
Example:
父窗口:// 假定 iframe 的 id = iframe
document.getElementById('iframe').contentWindow.postMessage('123','*');
子窗口:Window.addEventListener('message', ({ data}) => {console.log('data');
// 向父窗口发送消息
if(window.parrent !== window.self) {window.parrent.postMessage('456', '*');
}
})
参考资料
- MDN-Iframe
- HTML 标准 -iframe