深入浅出谈 iframe

HTML内联框架元素 <iframe> 表示 嵌套的 browsing context。它能够将另一个HTML页面嵌入到当前页面中。

1、定义与用法

iframe 元素会创建包含另外一个文档的内联框架(即行内框架)

HTML 与 XHTML 之间的差异

在 HTML 4.1 Strict DTD 和 XHTML 1.0 Strict DTD 中,不支持 iframe 元素

提醒和注释

把需要的文本放置在 <iframe></iframe> 之间,这样就可以应对无法理解 iframe 的浏览器

2、属性及其值

2.1、HTML5 中的新属性

属性描述
alignleftrighttopmiddlebottom不赞成使用。请使用样式代替。规定如何根据周围的元素来对齐此框架。
frameborder10规定是否显示框架周围的边框。
heightpixels*%*规定 iframe 的高度。
longdescURL规定一个页面,该页面包含了有关 iframe 的较长描述。
marginheightpixels定义 iframe 的顶部和底部的边距。
marginwidthpixels定义 iframe 的左侧和右侧的边距。
nameframe_name规定 iframe 的名称。
sandbox""allow-formsallow-same-originallow-scriptsallow-top-navigation启用一系列对 中内容的额外限制。
scrollingyesnoauto规定是否在 iframe 中显示滚动条。
seamlessseamless规定 看上去像是包含文档的一部分。
srcURL规定在 iframe 中显示的文档的 URL。
srcdocHTML_code规定在 中显示的页面的 HTML 内容。
widthpixels*%*定义 iframe 的宽度。

2.2、全局属性

支持HTML所有的全局属性

事件属性描述
accesskey规定激活元素的快捷键。
class规定元素的一个或多个类名(引用样式表中的类)。
contenteditable规定元素内容是否可编辑。
contextmenu规定元素的上下文菜单。上下文菜单在用户点击元素时显示。
data-*用于存储页面或应用程序的私有定制数据。
dir规定元素中内容的文本方向。
draggable规定元素是否可拖动。
dropzone规定在拖动被拖动数据时是否进行复制、移动或链接。
hidden规定元素仍未或不再相关。
id规定元素的唯一 id。
lang规定元素内容的语言。
spellcheck规定是否对元素进行拼写和语法检查。
style规定元素的行内 CSS 样式。
tabindex规定元素的 tab 键次序。
title规定有关元素的额外信息。
translate规定是否应该翻译元素内容。

2.3、事件属性

支持HTML中所有的事件属性

2.3.1、针对 window 对象触发的事件(应用到 body标签)
属性描述
onafterprintscript文档打印之后运行的脚本。
onbeforeprintscript文档打印之前运行的脚本。
onbeforeunloadscript文档卸载之前运行的脚本。
onerrorscript在错误发生时运行的脚本。
onhaschangescript当文档已改变时运行的脚本。
onloadscript页面结束加载之后触发。
onmessagescript在消息被触发时运行的脚本。
onofflinescript当文档离线时运行的脚本。
ononlinescript当文档上线时运行的脚本。
onpagehidescript当窗口隐藏时运行的脚本。
onpageshowscript当窗口成为可见时运行的脚本。
onpopstatescript当窗口历史记录改变时运行的脚本。
onredoscript当文档执行撤销(redo)时运行的脚本。
onresizescript当浏览器窗口被调整大小时触发。
onstoragescript在 Web Storage 区域更新后运行的脚本。
onundoscript在文档执行 undo 时运行的脚本。
onunloadscript一旦页面已下载时触发(或者浏览器窗口已被关闭)。
2.3.2、Form 事件

由 HTML 表单内的动作触发的事件(应用到几乎所有 HTML 元素,但最常用在 form 元素中):

属性描述
onblurscript元素失去焦点时运行的脚本。
onchangescript在元素值被改变时运行的脚本。
oncontextmenuscript当上下文菜单被触发时运行的脚本。
onfocusscript当元素获得焦点时运行的脚本。
onformchangescript在表单改变时运行的脚本。
onforminputscript当表单获得用户输入时运行的脚本。
oninputscript当元素获得用户输入时运行的脚本。
oninvalidscript当元素无效时运行的脚本。
onresetscript当表单中的重置按钮被点击时触发。HTML5 中不支持。
onselectscript在元素中文本被选中后触发。
onsubmitscript在提交表单时触发。
2.3.4、Keyboard 事件
属性描述
onkeydownscript在用户按下按键时触发。
onkeypressscript在用户敲击按钮时触发。
onkeyupscript当用户释放按键时触发。
2.3.5、Mouse 事件

由鼠标或类似用户动作触发的事件:

属性描述
onclickscript元素上发生鼠标点击时触发。
ondblclickscript元素上发生鼠标双击时触发。
ondragscript元素被拖动时运行的脚本。
ondragendscript在拖动操作末端运行的脚本。
ondragenterscript当元素元素已被拖动到有效拖放区域时运行的脚本。
ondragleavescript当元素离开有效拖放目标时运行的脚本。
ondragoverscript当元素在有效拖放目标上正在被拖动时运行的脚本。
ondragstartscript在拖动操作开端运行的脚本。
ondropscript当被拖元素正在被拖放时运行的脚本。
onmousedownscript当元素上按下鼠标按钮时触发。
onmousemovescript当鼠标指针移动到元素上时触发。
onmouseoutscript当鼠标指针移出元素时触发。
onmouseoverscript当鼠标指针移动到元素上时触发。
onmouseupscript当在元素上释放鼠标按钮时触发。
onmousewheelscript当鼠标滚轮正在被滚动时运行的脚本。
onscrollscript当元素滚动条被滚动时运行的脚本。
2.3.6、Media 事件

由媒介(比如视频、图像和音频)触发的事件(适用于所有 HTML 元素,但常见于媒介元素中,比如 、、、 以及 ):

属性描述
onabortscript在退出时运行的脚本。
oncanplayscript当文件就绪可以开始播放时运行的脚本(缓冲已足够开始时)。
oncanplaythroughscript当媒介能够无需因缓冲而停止即可播放至结尾时运行的脚本。
ondurationchangescript当媒介长度改变时运行的脚本。
onemptiedscript当发生故障并且文件突然不可用时运行的脚本(比如连接意外断开时)。
onendedscript当媒介已到达结尾时运行的脚本(可发送类似“感谢观看”之类的消息)。
onerrorscript当在文件加载期间发生错误时运行的脚本。
onloadeddatascript当媒介数据已加载时运行的脚本。
onloadedmetadatascript当元数据(比如分辨率和时长)被加载时运行的脚本。
onloadstartscript在文件开始加载且未实际加载任何数据前运行的脚本。
onpausescript当媒介被用户或程序暂停时运行的脚本。
onplayscript当媒介已就绪可以开始播放时运行的脚本。
onplayingscript当媒介已开始播放时运行的脚本。
onprogressscript当浏览器正在获取媒介数据时运行的脚本。
onratechangescript每当回放速率改变时运行的脚本(比如当用户切换到慢动作或快进模式)。
onreadystatechangescript每当就绪状态改变时运行的脚本(就绪状态监测媒介数据的状态)。
onseekedscript当 seeking 属性设置为 false(指示定位已结束)时运行的脚本。
onseekingscript当 seeking 属性设置为 true(指示定位是活动的)时运行的脚本。
onstalledscript在浏览器不论何种原因未能取回媒介数据时运行的脚本。
onsuspendscript在媒介数据完全加载之前不论何种原因终止取回媒介数据时运行的脚本。
ontimeupdatescript当播放位置改变时(比如当用户快进到媒介中一个不同的位置时)运行的脚本。
onvolumechangescript每当音量改变时(包括将音量设置为静音)时运行的脚本。
onwaitingscript当媒介已停止播放但打算继续播放时(比如当媒介暂停已缓冲更多数据)运行脚本

3、案例分析

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>iframe的使用</title>
    </head>
    <body>
        <iframe src="https://www.baidu.com" style="width:1000px;height: 500px;" name="baidu" scrolling="auto" sandbox="allow-same-origin">
        </iframe>
    </body>
</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VX3Bq34S-1585738968444)(D:\DAYNOTE\iframe1.PNG)]

可以看出,iframe的一些基本属性:

  • src iframe页面地址,有同域跨域之分
  • height iframe高度
  • width iframe宽度
  • name iframe命名,可通过window.frames[xxx]被调用
  • scrolling iframe滚动模式
  • sandbox html5新特性,用于限制iframe的功能

4、使用iframe的正确方法

我们可以通过 contentWindowcontentDocument两个API获取iframe的window对象和document对象。

let iframe = document.getElementById('demo');
let iwindow = iframe.contentWindow; // 获取iframe的window对象
let idoc = iframe.contentDocument; // 获取iframe的document对象

刚刚我们提到了iframe的name属性,我们也可以通过window.frames[iframeName]来调用iframe。

let iframe = window.frames['demo']

5、iframe使用父级内容正确方法

我们通过window.selfwindow.parentwindow.top这三个属性分别获取自身window对象,父级window对象,顶级window对象。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O6dNAZVn-1585738968446)(D:\DAYNOTE\iframe2.webp)]

iframe1.self === iframe1
iframe1.parent === iframe2
iframe2.parent === window
iframe1.top === window

6、同域/跨域

6.1、同域

js遵循同源策略,即同协议,同域名,同端口号

同源策略 是由Netscape提出的一个著名的安全策略,现在所有支持JavaScript 的浏览器都会使用这个策略。实际上,这种策略只是一个规范,并不是强制要求,各大厂商的浏览器只是针对同源策略的一种实现。它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。

6.2、跨域

指的是两个资源非同源。出于安全方面的考虑,页面中的JavaScript在请求非同源的资源时就会出 跨域问题,即跨域请求,这时,由于同源策略,我们的请求会被浏览器禁止。也就出现了 我们常说的 跨域 问题。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p6SJSUVT-1585738968446)(D:\DAYNOTE\跨域.webp)]

6.2.1、iframe跨域通讯之document.domain

对于主域相同子域不同的两个页面,我们可以通过document.domain + iframe来解决跨域通信问题。

网页A(http://www.easonwong.com)和网页B(http://script.easonwong.com),两者都设置document.domain = 'easonwong.com'(这样浏览器就会认为它们处于同一个域下),然后网页a再创建iframe上网页b,就可以进行通信。

网页A

document.domain = 'easonwong.com';
var ifr = document.createElement('iframe');
ifr.src = 'http://script.easonwong.com';
ifr.style.display = 'none';
document.body.appendChild(ifr);
ifr.onload = function(){
    let doc = ifr.contentDocument || ifr.contentWindow.document;
    // 在这里操纵b.html
};

网页B

document.domain = 'easonwong.com';
6.2.2、iframe跨域通讯之postMessage

postMessage是html5的新特性

我们可以通过html5这个新特性进行iframe间的跨域通信,使用postMessage进行数据传递,通过Message监听通信事件。

网页a

document.domain = 'easonwong.com';
var ifr = document.createElement('iframe');
ifr.src = 'http://script.easonwong.com';
ifr.style.display = 'none';
document.body.appendChild(ifr);
// 发送数据
ifr.postmessage('hello, I`m a', 'http://script.easonwong.com');

网页b

// 监听message事件
window.addEventListener('message', receiver, false);
function receiver(e) {
    if (e.origin == 'http://www.easonwong.com') {
        if (e.data == 'hello, I`m a') {
            e.source.postMessage('hello, I`m b', e.origin);信息
        }
    }
}

7、iframe实现JSBridge

在移动端Hybrid混合模式中经常用到JSBridge进行JS和Native之间的通信,其中我们可以通过iframe的方式实现JS调用Native的方法。

以上提到的方法就是URL SCHEME拦截。

URL SCHEME是一种类似于url的链接,是为了方便app直接互相调用设计的,形式和普通的 url 近似,主要区别是 protocol 和 host 一般是自定义的,例如: easonwong://hh/url?name=easonwong,其中protocol是easonwong,host则是hh。

我们通过创建一个iframe(src设为我们自定义的URL SCHEME)来发送请求,然后Native那边可以拦截到请求并获取其中带有的参数,即可进行后续的操作。

8、iframe的其他用途

  • 用iframe进行异步请求:在很久很久很久以前,久到ajax还没出现的时候,人们会用iframe来进行异步请求。大概就是异步创建iframe,然后后台返回数据在iframe中,我们在从里面获取数据。例如在我做过的一个项目中,通过iframe.src传入一个文件下载地址,实现无需打开新窗口下载文件。

  • 引用/展示第三方内容

  • 需要独立样式和带有交互的内容,例如幻灯片

  • sandbox沙箱隔离

  • 历史记录管理

9、iframe的安全问题

9.1、iframe小广告

很让我们讨厌iframe的一点,就是很多*网站都会有各种让人防不胜防的小广告,它们大多就是用通过iframe实现的,本来想点击某个播放按钮,结果马鸭直接跳几十跳不知道去了哪个新世界去了。

更讨厌的一种情况是,可能不知道哪天用户突然拿刀过来,说我们的项目页面里出现了野鸡广告,说我们在消费他们,一脸懵逼的我们觉得十分无辜。实际上就是我们的页面被运行商劫持了,被挂上了注入了不知名的野鸡广告。

所以我们一定要注意在用iframe的同时,要防止我们被iframe了。

9.2、防嵌套页面操作

在前端领域,我们可以通过window.top来防止我们页面被嵌套。

if(window != window.top){
    window.top.location.href = myURL;
}

或者通过window.location.host来检测是否跨域了

if (top.location.host != window.location.host) {
  top.location.href = window.location.href;
}

而后端也可以做对应的防范措施,通过设置X-Frame-Options响应头来确保自己网站的内容没有被嵌到别人的网站中去,也从而避免了点击劫持 (clickjacking) 的攻击。

9.3、CSP

内容安全策略(CSP)用于检测和减轻用于 Web 站点的特定类型的攻击,例如 XSS 和数据注入等。

MDN CSP

通过CSP配置sandbox和child-src可以设置iframe的有效地址,它限制适iframe的行为,包括阻止弹出窗口,防止插件和脚本的执行,而且可以执行一个同源策略。

用法

  • 我们可以在html头部中加上 <meta> 标签
    <meta http-equiv="Content-Security-Policy" content="child-src 'unsafe-inline' 'unsafe-eval' www.easonwong.com">
  • 或者通过HTTP头部信息加上Content-Security-Policy字段
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值