iframe的介绍
iframe元素会创建包含另外一个文档的内联框架(即行内框架)。可以使用iframe在页面中嵌入其他文档,例如另一个页面或者是一个视频。
注意:当站点启用了https那么使用iframe引入的页面也需要是https。
iframe 对象(相对重要的属性)
| 属性 | 描述 |
|---|---|
| src | 规定在 iframe 中显示的文档的 URL。 |
| contentDocument | 返回 iframe 生成的 document 对象。 |
| contentWindow | 返回 iframe 生成的 window 对象。 |
| longDesc | 规定一个页面,该页面包含了有关 iframe 的较长描述。 |
| name | 规定 iframe 的名称。 |
| sandbox | 启用一系列对 iframe 中内容的额外限制。 |
| scrolling | 规定是否在 iframe 中显示滚动条 |
| seamless | 设置或返回 iframe 是否应该看起来像是包含文档的一部分(无边框或滚动条)。 |
| srcdoc | 规定在 iframe 中显示的页面的 HTML 内容。 |
iframe 内嵌 iframe。对应的
window对象会形成一个层次结构
window.frames—— “子”窗口的集合(用于嵌套的 iframe)。window.parent—— 对“父”(外部)窗口的引用。window.top—— 对最顶级父窗口的引用。
iframe 优缺点
优点
- 可以增加代码的可重用 用于多个网页
- 并行加载脚本
- 遇到加载缓慢的第三方内容如图标和广告,可以用iframe解决
缺点
- iframe会阻塞主页面的onload事件
- iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载
- iframe会不利于搜索引擎优化(SEO)
- 兼容性差
通信
postMessage
postMessage() 方法用于安全地实现跨源通信
发送消息 用 postMessage
otherWindow.postMessage(message, targetOrigin, [transfer])
- otherWindow 其他窗口的一个引用,比如 iframe 的 contentWindow 属性、执行 window.open 返回的窗口对象、或者是命名过或数值索引的 window.frames。
- message 将要发送到其他 window的数据。
- targetOrigin 指定哪些窗口能接收到消息事件,其值可以是 *(表示无限制)或者一个 URI。
- transfer 可选,是一串和 message 同时传递的 Transferable 对象。这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。
接收消息 监听 "message" 事件
接收程序有一个事件监听器,监听 "message" 事件,同时我们要验证消息来源地址,以确保是个可信的发送地址。
window.addEventListener('message', function (e) {
alert(e.origin) // 消息源的 URI(可能包含协议、域名和端口),用来验证数据源。
alert(e.source) // 消息源,消息的发送窗口/iframe。
alert(e.data) // 发送过来的数据。
}
####举个🌰
// a.html
<body>
<div>
<input id="text" type="text" value="suhonny" />
<button id="sendMessage">发送消息</button>
</div>
<iframe loading="lazy" id="receiver" src="https://localhost:8807/b.html" width="400" height="400">
<p>你的浏览器不支持 iframe。</p>
</iframe>
<script>
window.onload = function () {
// 拿到 iframe 的 window 对象
const receiver = document.getElementById('receiver').contentWindow;
const btn = document.getElementById('sendMessage');
btn.addEventListener('click', function (e) {
e.preventDefault();
let val = document.getElementById('text').value;
// receiver.postMessage("Hello " + val, "*"); 可以用 * 不限制
receiver.postMessage("Hello " + val, "https://localhost:8807");
});
}
</script>
</body>
// b.html
<body>
<div id="Message">Hello csc!</div>
<script>
window.onload = function () {
var Ele = document.getElementById('Message');
window.addEventListener('message', function (e) { // 监听 message 事件
if (e.origin !== "https://localhost:8807") return false // 验证消息来源地址
Ele.innerHTML = e.origin + e.data;
});
}
</script>
</script>
</body>
注意点:正确的文档在 iframe.onload触发时就位。但是,只有在整个 iframe 和它所有资源都加载完成时iframe.onload才会触发 因此在iframe资源加载完成前 不能进行其他操作
小知识
关于iframe中的cookie
- iframe 嵌套,每层都互相跨域的页面,最内层的依然可以访问最外层的 cookie
- domain相同时,跨窗口的cookie的值会发生覆盖 cookie 也受 domain 的影响。如果cookie 的 domain不一致则不能互相访问、修改;
获取 iframe 的 window 对象的另一个方式
- 通过索引获取:window.frames[0] —— 文档中的第一个 iframe 的 window 对象。
- 通过名称获取:window.frames.iframeName —— 获取 name="iframeName" 的 iframe 的 window 对象。