iframe 标签是 HTML 中便利的一种嵌入方式,让我们可以在当前 Web 页面中插入另一个 HTML 文档。最初的设计意图,是通过 iframe 嵌入广告或其它独立的内容,避免影响主页面的加载。
基本用法
iframe 标签的基本用法很简单,你只需要设置 src
属性指向你想在 iframe 中显示的页面即可。
🌰:<iframe src="https://www.baidu.com"> </iframe>
这样,我们就在当前页面中嵌入了一个页面 www.baidu.com。
iframe的属性
除了 src
外,iframe 标签还有诸多属性可供选择,如 width
、height
设置 iframe 的宽和高,frameborder
设置边框,scrolling
设置是否出现滚动条等等。
-
width
和height
: 这两个属性是用来设定 iframe 框架的宽度和高度。可以设定为像素值或百分比。🌰:
<iframe src="https://www.baidu.com" width="500" height="300"></iframe>
-
frameborder
:此项用来设定 iframe 边框的显示与否。其取值为'1'(表示显示边框)或者'0'(表示不显示边框)。🌰:
<iframe src="https://www.baidu.com" frameborder="1"></iframe>
-
scrolling
:这个属性用来设定当 iframe 的内容超过其设定的高度或宽度时是否显示滚动条。它有三个取值:'auto'(自动), 'yes'(始终显示滚动条, 或者 'no'(从不显示滚动条)。🌰:
<iframe src="https://www.baidu.com" scrolling="yes"></iframe>
iframe的优点
-
打破了浏览器足迹的限制:可以在同一个页面内进行独立的滚动、独立的刷新操作。
-
保护隐私:iframe 网页和主网页之间,不存在 JavaScript 的直接通信能力。
( 在不使用额外的跨域技术,如
postMessage
等的情况下,如果 iframe 网页和主网页不同源(源由协议,域名和端口三者确定),那么主网页中的 JavaScript 代码就不能直接访问和控制 iframe 网页中的内容,反之亦然。这种限制是基于浏览器的同源策略,该策略是浏览器对 JavaScript 强加的安全限制,只有同源的网页才可以共享 JavaScript 的对象,所以称为同源策略。目的就是为了防止来自不同源的脚本之间进行互相操作,以此保护用户的隐私安全。
举个例子,假设你在网页A(假设源为www.example-A.com)中插入了一个网页B的iframe(假设源为www.example-B.com), 由于同源策略,网页A中的 JavaScript 就不能直接获取和操作来自B网页的 DOM 节点、Cookie、LocalStorage 等数据,这样做的目的,就是防止恶意的第三方网站获取和利用你的私人数据。
同源策略并不是不能被突破的,例如之前提到的使用
postMessage
进行跨域通信,或者服务器端设置CORS
等方式都可以实现跨域通信。然而这些都需要开发者有意识地去开启,不会无意识地泄露用户数据。)
iframe的缺点
-
增加网页加载时间:每一个 iframe 都需要浏览器发起一次新的 HTTP 请求。
-
会阻碍主页面的加载。
-
不容易做到响应式设计。
iframe的工作机制
iframe 实际上是创建了一个完全独立的、嵌入到当前 DOM 中的新的浏览器环境,其内部的 HTML 文档与外部的主 HTML 文档相互独立。iframe内的文档有自己独立的 window对象、document对象,甚至包括 cookie,都与主页面相独立。这种特性使得 iframe 可以实现很多我们想要的功能,比如内嵌广告,载入独立应用等。
iframe在实际项目中的应用
-
异步文件上传:典型用法是配合 form 表单实现无刷新的文件上传,即在表单提交后,服务器返回一个新的网页加载在 iframe 内,这个页面一般包含一段脚本来通知主页面上传成功或失败。
-
模块化:利用 iframe 可以方便地实现不同模块的独立开发和部署,iframe 内部就像一个沙盒环境,可以隔离一些全局变量的污染。
-
第三方内容嵌入:因为iframe相当于创建了一个新的浏览器环境,使得我们可以比较安全地打开第三方网页。
( 通过将第三方内容封装在一个独立的 iframe 中,可以有效地隔离主页面与第三方内容之间的互相影响和潜在的安全风险。)
跨域的问题与跨域解决方案
跨域是使用 iframe 标签最常见的问题。我们无法访问或者操作 iframecontentWindow
对象的属性和方法,原因就是同源策略的限制。解决这类问题的主要方式是使用 HTML5 提供的 window.postMessage()
方法,用于在不同窗口间传递数据。
我们需要明确什么是跨域问题。在浏览器的同源策略下,两个页面必须来自同一协议、主机和端口,才能访问彼此的属性和方法。当一个页面尝试访问来自不同源(协议/主机/端口至少有一项不同)的页面的对象时,就会触发跨域限制。
window.postMessage()
是一种浏览器内置的方法,能够允许来自不同源的页面进行受限的通信,从而突破这种限制。使用这个方法的页面可以向任何监听了 message
事件的页面发送消息,无论这个页面是否同源。消息接收者可以通过检查 event.origin
属性来确定消息源的可信度,并决定是否对消息进行响应。
js
// 父页面
const iframeEl = document.getElementById('myIframe');
iframeEl.contentWindow.postMessage('我是父页面', 'https://example.com');
iframe 接收到消息后,会触发自己的 message
事件,我们可以监听这个事件并做出响应:
js
// iframe页面
window.addEventListener('message', function(event) {
// 检查消息源是否可信
if (event.origin !== 'https://example.com') return;
// 响应消息
console.log('消息已接收,内容为:' + event.data);
}, false);
示例中的'example.com', 需要替换为你们真实的源地址。这样,我们就可以实现跨域通信了。
这是一个简单的例子,实际的情况可能会复杂得多,需要根据具体的需求和上下文来定制你的代码。但这个例子大概展示了如何使用 window.postMessage()
突破同源限制。
补充说明
-
考虑到安全因素,一些网站会禁止其网页被其他页面通过 iframe 嵌入。对此,我们需要尊重原网站的设置,不强行通过技术手段对其进行嵌入。
-
使用 iframe 的时候需要注意性能问题。因为 iframe 会创建一个新的 window 环境,其内部的 JavaScript 脚本性能消耗将会独立于主页面,过多且滥用 iframe 可能会导致页面性能下降。
-
对 SEO(搜索引擎优化)有影响。搜索引擎可能不会把 iframe 中的内容算作你的网页内容,因此如果你的网站需要 SEO 优化,需要谨慎使用 iframe。
-
由于 iframe 的内容是独立加载的,所以如果网页中包含多个 iframe,可能会导致页面加载速度变慢,影响用户体验。