iframe杂记乱谈

191 阅读5分钟

一、什么是iframe

HTML 内联框架元素 (<iframe>)  表示嵌套的browsing context。它能够将另一个 HTML 。页面嵌入到当前页面中。
它最初由微软公司在Internet Explorer 3中推出。iframe的出现主要是为了解决网站内嵌内容的安全隐患问题。在网站内嵌内容时,如果直接引用外部网站的资源,可能会存在跨域问题,这时候使用iframe就可以解决这个问题,因为iframe中的内容是被放在一个独立的HTML文档中,在这个文档中引用外部资源就不会存在跨域问题了。

然而,在那个网速很慢的年代,一些开发者通过这种方式把页面切分成不同的模块,从而优化整体的加载速度,但这样做会导致很大的开发与维护成本(微前端实现方式之一)。因此,虽然iframe在某些情况下是有用的,但XHTML最后没有获得大规模的使用。

随着时间的推移,iframe经历了更多的变化和改进。比如,它可以用于实现网页中的异步加载,提高用户体验。同时,它也支持各种属性和方法,例如srcwidthheight等,使用户可以更方便地控制和管理嵌入的内容。

二、基础使用

iframe特性全解读
<iframe>标签生成一个指定区域,在该区域中嵌入其他网页。它是一个容器元素,如果浏览器不支持<iframe>,就会显示内部的子元素。

 <iframe width="400px" height="400px" src="https://www.bookstack.cn/read/html-tutorial/spilt.1.docs-iframe.md">
    <p><a href="https://www.bookstack.cn/read/html-tutorial/spilt.1.docs-iframe.md">基本用法-阮一峰</a></p>
</iframe>

上面的代码在当前页面嵌入了www.bookstack.cn/read/html-t… ,宽高都设置了400px。如果当前浏览器不支持iframe标签,则会显示链接。 整体来说iframe的支持性还是非常好的,所以内部内容不写也是可以的。

iframe的属性包括:

  • align:规定如何根据周围的元素对齐此框架。
  • border:规定是否显示框架周围的边框。
  • height:规定iframe的高度。
  • importance:浏览器下载嵌入的网页的优先级,可以设置三个值。high表示高优先级,low表示低优先级,auto表示由浏览器自行决定。
  • longdesc:定义一个页面,该页面包含有关iframe的较长描述。
  • marginheight:定义iframe的顶部和底部的边距。
  • marginwidth:定义iframe的左侧和右侧的边距。
  • name:规定iframe的名称。
  • scrolling:规定是否在iframe中显示滚动条。
  • src:规定在iframe中显示的文档的URL。
  • sandbox: 是限制嵌入内容所具有的权限,例如,可以阻止嵌入的页面执行脚本、提交表单或访问其他域名。这使得sandbox能够防止恶意内容对父页面进行攻击,如禁用插件、禁止其他浏览上下文的导航、禁止弹出窗口和模式对话框
  • width:规定iframe的宽度。

三、通信

获取子页面里的内容(同域)

主要两个API就是contentWindowcontentDocument
iframe.contentWindow获取iframe中的window对象。
iframe.contentDocument获取iframe中的document对象。

<body class="main">
    <h2>这是最顶层页面</h2>
    <iframe src="./iframe1.html" frameborder="1" id="iframe1" width="600px" height="600px" name="iframe1"></iframe>
    <script>
        // 方式一:获取iframe的dom
        var iframe1 = document.getElementsByTagName('iframe')[0];
        
        // 方法二:获取iffame的dom
        var iframe1 = window.frames['iframe1'];
        console.log('iframe1==========', iframe1);
        console.log('iframe1 window==========', iframe1.contentWindow);
        console.log('iframe1 document==========', iframe1.contentDocument);
    </script>
</body>

image.png

子页面中获取父级内容(同域)

在同域下,子叶main同样也能操作父页面内容。在iframe中,可以通过在window上挂载的几个API进行获取. window.parent 获取上一级的window对象,如果还是iframe则是该iframe的window对象 window.top 获取最顶级容器的window对象,即,就是你打开页面的文档 window.self 返回自身window的引用。可以理解 window===window.self(脑残)

如下结果,灰色嵌套粉红色,粉红色嵌套红色。假设三层的window对象分别是window、window1和window2。那

window2.self === window2
window2.parent === window1
window2.top === window

image.png

postMessage(同域名、跨域)

MDN-window.postMessage 使用场景:子页面给主页面发信息。

// 子页面
 window.parent?.postMessage?.('logout', '*');
// 主(父页面)
window.addEventListener('message', event => {
    // console.log('receive message from iframe: ', event.data);
    if (event.data === 'logout') {
        logoutSystem();
    } 
});

路由传参数

可以将子页面需要的参数放到iframe的src上面,如下:

<iframe
    src="**/center/iframe/sidebar/model"
    width="100%"
    frameborder="no"
></iframe>

四、子页面适配主页面样式

window.parent

子页面中判断window.parent属性的值是否存在,如果存在则表示为iframe嵌套,则修改样式

contentWindow?.document(同域)

在主页面中直接修改子页面样式。但在实践中,要求主页和子页面同域名,且需要一个定时任务来保证修改的准确性。
示例如下:

<template>
 
    <iframe
        id="iframe"
        :src="iframeSrc"
        width="100%"
        frameborder="no"
        @load="handleLoaded"
    ></iframe>
</template>
<script setup lang="ts">
import {ref, onUnmounted} from 'vue';
const iframeSrc = ref('http://baidu.com');

let interval = null;
function handleLoaded(event) {
    const iframe: any = document.getElementById('iframe');
    
    // 无法保证js执行的时候,子页面dom已经加载完成,所以使用了一个定时任务
    timer = setInterval(() => {
        const header = iframe.contentWindow?.document?.getElementsByClassName('main-header')?.[0];
        if (header) {
            clearInterval()
            header.style.display = 'none';
        }
    }, 500);
}
onUnmounted(() => {
    clearInterval(timer);
});
</script>

五、作用

广告

使用iframe来做广告的原因主要有以下几点:

  1. 避免广告代码对主页面的影响:通过将广告嵌入到页面中的iframe中,可以避免广告代码对主页面的影响,提高用户体验。
  2. 增加网页安全性:使用iframe嵌入广告内容,可以减少广告代码与主页面的交互,从而降低安全风险。
  3. 更好地控制广告展示:使用iframe来展示广告,可以更好地控制广告的展示效果,例如调整广告的布局、尺寸等。
  4. 提高广告点击率:由于iframe中的广告内容与主页面是分开的,因此用户在点击广告时,可以直接进入广告页面,从而提高广告的点击率。

多个产品同一个平台展示

多个应用在一个平台上进行展示。这儿的作用类似微前端。是我的一个具体的项目实践。具体改造还挺多的,今天不想写啦,等我想写的时候,再写一个iframe的实践吧。

六、后记

这个文章草稿还是一年前的,当时想的是每周写一篇文章,但是 但是 懒了,没有付出实际行动。