目录
基本概念
iframe(内联框架) 是HTML中的一个用于将其他网页或文档嵌入到本网页中的标签。通过 iframe
,你可以在当前网页中船舰一个显示另一个完全独立的网页的子窗口。如下:用B站测试
<iframe src="https://www.bilibili.com/"></iframe>
应用场景
- 嵌入视频:如 YouTube、Vimeo 等视频平台提供的嵌入代码
- 加载广告:广告常常通过 iframe 嵌入,以确保广告内容与主页面隔离
- 网页嵌套:将一个完全独立的页面嵌入到当前页面中,比如加载第三方应用、表单等
- 内嵌文档:将 PDF、HTML、网站等文件展示在网页中
- 跨域通信:通过 iframe 可以显示来自不同域名的内容,但需要考虑一些安全限制
- 异步加载:iframe可实现内容的异步加载,在不阻塞主页面加载的情况下,加载嵌入的内容
- 安全隔离:通过沙箱属性等设置,可以实现iframe中的内容与其他网页的隔离,提高安全性
常见属性
属性 | 描述 |
src | 指定要嵌入的网页或文档的URL |
srcdoc | 直接在 iframe 标签中嵌入 HTML 内容,而不是通过 src 属性加载外部文档。 |
frameborder | 指定iframe的边框是否可见,0:不显示边框;1:显示边框(默认)srcdoc |
scrolling | 指定是否显示滚动条。yes(始终显示滚动条);no(始终不显示滚动条);auto(根据内容的大小自动显示或隐藏滚动条) |
name | 指定iframe的名称,以便在其他地方引用 |
loading | 指定iframe加载时的行为 |
importance | 指定iframe对页面内容的重要性。auto (重要性由浏览器根据上下文自动决定);high (非常重要的,可能会影响页面的加载优先级和资源分配) |
allow | 由空格分隔的功能列表,这些功能在嵌入的内容(如视频、地图等)中是被允许访问的。如:fullscreen:全屏显示;geolocation:地理位置;microphone:麦克风;camera:摄像头。 |
allowpaymentrequest | 指定是否允许在iframe中的内容进行支付请求。true(允许);false(拒绝) |
referrerpolicy | 指定如何发送referer HTTP标头,这个标头通常包含了请求的来源地址。 referrerpolicy属性的值可以包括:
|
sandbox | 启用iframe的沙箱模式。沙箱环境可以限制iframe中的脚本执行权限,提高安全性。 |
allowfullscreen | 指定是否允许在iframe中使用全屏模式。true:允许全屏显示,false:不允许全屏显示 |
和其它div标签作用相同的属性 | class(类名),style(样式),width和height(宽高),title(标题) |
srcdoc属性演示: 在iframe中嵌入HTML代码而不是外部文档
<iframe srcdoc="<html><body><h1>Hello, World!</h1></body></html>"></iframe>
跨域通信
受限于浏览器的同源策略,当iframe嵌入的页面与父页面或与其他iframe嵌入的页面不属于同源时,就会受到跨域限制,导致无法直接通过JS进行访问或操作。
但我们可以使用 HTML5提供的postMessage API 来在不同源的窗口或iframe之间安全地传递数据。
父页面向iframe发送消息:
<iframe id="myFrame" src="https://www.another-site.com"></iframe>
<script>
const iframe = document.getElementById('myFrame');
iframe.contentWindow.postMessage('Hello from parent', '*');
</script>
'*'
表示消息可以发送到任何来源的 iframe
。但为了安全起见,最好指定一个确切的来源。
iframe 接收消息并回应:
<script>
//使用 window.addEventListener('message', callback) 来监听消息
window.addEventListener('message', function(event) {
console.log('Received message:', event.data);
// 确认消息来源的安全性
if (event.origin === 'https://www.example.com') {
// 回复消息
event.source.postMessage('Hello from iframe', event.origin);
}
});
</script>
性能安全
虽然 <iframe> 标签可以很方便地实现上述功能,但是需要注意以下几点:
嵌入的网页可能会影响页面性能和加载速度,特别是当嵌入的网页包含大量的资源(如图片、CSS 和 JavaScript)时。
嵌入的网页可能会被恶意攻击者用于钓鱼或注入恶意代码的攻击,因此需要谨慎使用。比如
点击劫持(Clickjacking):攻击者可以利用 iframe 将一个网页嵌入到透明的 iframe 中,诱导用户点击,从而劫持用户操作。这种情况下,用户以为在操作当前页面,实际上在点击 iframe 内的内容。
微前端应用
微前端:
在微前端架构中,iframe可以作为一个容器,用于加载和展示不同的微前端应用。iframe作为一个HTML标签,具有简单易用、天然隔离等优势,但也存在性能开销、通信困难等缺点。所以在简单场景和快速原型开发中,它仍然是实现微前端的一种有效方式。然而,对于复杂应用和高性能要求场景,需要谨慎考虑iframe的使用。
下面是一个iframe实现微前端的简单方案:
主应用:
// 主应用 引入子应用 // 通过 iframe
<iframe
allowfullscreen="true"
id="iframe"
:src="url"
width="100%"
height="100%"
scrolling="No"
frameborder="0"
></iframe>
// 主应用 接口 iframe 子应用页面数据
window.onmessage = (params) => {
console.log('子应用传来的数据', params)
}
// 主应用 向iframe 子应用发送数据
let iframe = document.getElementById('iframe').contentWindow
iframe.postMessage(params, '*')
子应用:
// 子应用接收主应用传来的数据
window.addEventListener('message', async (params) => {
console.log('接收主应用消息', params)
})
//子应用给主应用发送数据
let obj = { xxx: xxx }
window.parent.postMessage(obj, '*')
// 子应用移除监听
window.removeEventListener('message', () => {})
若有错误或描述不当的地方,烦请评论或私信指正,万分感谢 😃