iframe(内联框架)是HTML中的一个标签,用于在网页中嵌入另一个网页或文档。它允许将一个网页嵌入到另一个网页中,并在父页面中显示嵌入的内容。
通过使用iframe标签,可以在一个网页中显示来自不同源的内容,例如嵌入其他网站的页面、视频、地图等。iframe提供了一种简单的方法来集成不同来源的内容,并将其显示在一个页面中,而不需要用户离开当前页面。
基本语法:
<iframe src="URL" width="width" height="height"></iframe>
其中,src
属性指定要嵌入的内容的URL,width
和height
属性指定iframe的宽度和高度。
一、应用场景
iframe的页面和父页面(parent)是分开的,不受 parent的CSS或者全局的JavaScript的影响。
1.网页编辑器;
2.跨域通信。JavaScript跨域总结与解决办法 ,类似的还有浏览器多页面通信,比如音乐播放器,用户如果打开了多个tab页,应该只有一个在播放;
3.历史记录管理,解决ajax化网站响应浏览器前进后退按钮的方案,在html5的history api不可用时作为一种替代;
4.纯前端的utf8和gbk编码互转。比如在utf8页面需要生成一个gbk的encodeURIComponent字符串,可以通过页面加载一个gbk的iframe,然后主页面与子页面通信的方式实现转换;
5.用iframe实现无刷新文件上传,在FormData不可用时作为替代方案;
6.创建一个全新的独立的宿主环境。iframe还可以用于创建新的宿主环境,用于隔离或者访问原始接口及对象,比如有些前端安全的防范会覆盖一些原生的方法防止恶意调用,通过创建一个iframe,然后从iframe中取回原始对象和方法来破解这种防范;
7.用来加载广告,例如联盟广告;
8.一般邮箱使用iframe,如QQ邮箱;
9.一些简单的后台页面。
二、优缺点
优点:
-
内容分离:通过使用iframe,可以将不同来源的内容分离开来。这意味着可以在一个网页中嵌入来自不同域名或服务器的内容,使网页更加模块化和可维护。例如,可以将地图、视频、社交媒体小部件等嵌入到网页中,而不需要编写复杂的代码。
-
简单集成:iframe提供了一种简单的方法来集成其他网站或服务的内容。只需提供要嵌入的内容的URL,设置适当的宽度和高度,即可在父页面中显示嵌入的内容。这使得在网页中显示外部内容变得非常容易。
-
并行加载:使用iframe可以实现并行加载。当页面包含多个iframe时,浏览器可以同时加载这些iframe中的内容,从而提高页面加载速度和性能。这对于包含大量媒体内容或需要从不同服务器加载数据的网页特别有用。
-
独立滚动:每个iframe都有自己的滚动条,可以独立于父页面进行滚动。这对于嵌入较长的内容或具有固定高度的内容非常有用。用户可以在iframe中滚动以查看全部内容,而不会影响到父页面的滚动。
-
广告和内容隔离:通过将广告代码嵌入到单独的iframe中,可以实现广告和网页内容的隔离。这可以防止广告代码对网页的样式和功能产生负面影响,并提高网页的稳定性和安全性。
缺点:
-
安全风险:由于iframe可以嵌入来自不同源的内容,存在安全风险。恶意网站可以通过iframe来进行点击劫持攻击,将用户误导到恶意网页或执行恶意操作。此外,如果嵌入的内容来自不可信的源,可能存在跨站脚本攻击(XSS)的风险。因此,在使用iframe时,需要谨慎考虑安全性,并确保嵌入的内容来自可信任的源。
-
SEO(搜索引擎优化)问题:搜索引擎可能对iframe中的内容处理不够友好。搜索引擎爬虫可能无法正确解析和索引嵌入在iframe中的内容,导致嵌入的内容无法被搜索引擎收录和显示在搜索结果中。这可能影响网页的可搜索性和可发现性。
-
页面加载性能:如果网页中包含大量的iframe,每个iframe都需要加载其自身的内容,这可能会增加页面的加载时间和带宽消耗。特别是当嵌入的内容较大或来自远程服务器时,加载时间可能会延长,影响用户体验。
-
交互体验限制:由于浏览器的安全策略,跨域的iframe之间的通信受到限制。这意味着在父页面和嵌入的iframe之间进行数据传递和交互可能会受到限制。如果需要实现复杂的交互功能,可能需要额外的处理和技术手段。
-
响应式设计困难:在设计响应式网页时,要确保嵌入的iframe能够适应不同屏幕尺寸和设备。由于iframe具有固定的宽度和高度,可能需要额外的调整和适配,以确保在不同设备上正常显示。
三、使用方法
场景:项目A中点击某个按钮,跳转到项目B,项目B中的交互能够影响项目A中的交互逻辑,可以考虑使用iframe,在项目A中嵌入项目B,通过postmessage通信。
postMessage是一个用于在不同窗口或iframe之间进行跨域通信的方法。它允许一个窗口向另一个窗口发送消息,并通过事件监听器接收和处理这些消息。
postMessage方法接受两个参数:
-
message:要发送的消息内容。可以是字符串、数字、对象或数组等数据类型。这个参数是必需的。
-
targetOrigin:指定目标窗口的源,即消息发送到哪里去。它可以是一个具体的域名(如"http://example.com")
或一个通配符("*"),表示允许来自任何源的窗口接收消息。这个参数是可选的,但为了安全起见,建议始终提供目标窗口的确切源。
假设有两个不同源的页面,iframePage.html
是index.html
的子页面:
<!-- index.html -->
<body style="border:5px solid #333;">
<h1>this is index</h1>
<iframe src="./iframePage.html" id='myframe'></iframe>
</body>
<!-- iframePage -->
<body style="border:5px solid #333;">
<h1>this is iframePage</h1>
</body>
这两个页面是无法通信,因为它们是不同源的(跨域),可以使用postMessage解决
。
从父页面向子页面发送一条消息:
<script>
// idnex.html
//获取iframe元素
iFrame = document.getElementById('myframe')
//iframe加载完毕后再发送消息,否则子页面接收不到message
iFrame.onload = function(){
//iframe加载完立即发送一条消息
iFrame.contentWindow.postMessage('MessageFromIndex1','*');
}
</script>
postMessage
是挂载在window
对象上的,等iframe
加载完毕后,用iFrame.contentWindow
获取到iframe
的window
对象,然后调用postMessage
方法,相当于给子页面发送了一条消息。
消息发送到iframePage.html
,在子页面接收message:
<script>
// iframePage.html
//回调函数
function receiveMessageFromIndex ( event ) {
console.log( 'receiveMessageFromIndex', event )
if(event.data==='MessageFromIndex1'){
//todo
}
}
//监听message事件
window.addEventListener("message", receiveMessageFromIndex, false);
</script>
event
对象中的data
属性存放着我们从父页面传过来的数据
从子页面发送数据给父页面:
<script>
// iframePage.html
//给父页面发送消息,data为对象
parent.postMessage( {msg: 'MessageFromIframePage'}, '*');
</script>
父页面接收数据:
<script>
//index.html
//回调函数
function receiveMessageFromIframePage (event) {
console.log('receiveMessageFromIframePage', event)
}
//监听message事件
window.addEventListener("message", receiveMessageFromIframePage, false);
</script>
总结:
1.父窗口给子窗口发送消息,其实就是在父窗口中操作子窗口发消息,然后让子窗口接收自己刚才发的消息。
2.子窗口给父窗口发送消息,其实就是在子窗口中操作父窗口发消息,然后让父窗口接收自己刚才发的消息。