深入浅出谈 iframe

HTML内联框架元素 之间,这样就可以应对无法理解 iframe 的浏览器

2、属性及其值

2.1、HTML5 中的新属性

属性 描述
align leftrighttopmiddlebottom 不赞成使用。请使用样式代替。规定如何根据周围的元素来对齐此框架。
frameborder 10 规定是否显示框架周围的边框。
height pixels*%* 规定 iframe 的高度。
longdesc URL 规定一个页面,该页面包含了有关 iframe 的较长描述。
marginheight pixels 定义 iframe 的顶部和底部的边距。
marginwidth pixels 定义 iframe 的左侧和右侧的边距。
name frame_name 规定 iframe 的名称。
sandbox ""allow-formsallow-same-originallow-scriptsallow-top-navigation 启用一系列对 中内容的额外限制。
scrolling yesnoauto 规定是否在 iframe 中显示滚动条。
seamless seamless 规定 看上去像是包含文档的一部分。
src URL 规定在 iframe 中显示的文档的 URL。
srcdoc HTML_code 规定在 中显示的页面的 HTML 内容。
width pixels*%* 定义 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标签)
属性 描述
onafterprint script 文档打印之后运行的脚本。
onbeforeprint script 文档打印之前运行的脚本。
onbeforeunload script 文档卸载之前运行的脚本。
onerror script 在错误发生时运行的脚本。
onhaschange script 当文档已改变时运行的脚本。
onload script 页面结束加载之后触发。
onmessage script 在消息被触发时运行的脚本。
onoffline script 当文档离线时运行的脚本。
ononline script 当文档上线时运行的脚本。
onpagehide script 当窗口隐藏时运行的脚本。
onpageshow script 当窗口成为可见时运行的脚本。
onpopstate script 当窗口历史记录改变时运行的脚本。
onredo script 当文档执行撤销(redo)时运行的脚本。
onresize script 当浏览器窗口被调整大小时触发。
onstorage script 在 Web Storage 区域更新后运行的脚本。
onundo script 在文档执行 undo 时运行的脚本。
onunload script 一旦页面已下载时触发(或者浏览器窗口已被关闭)。
2.3.2、Form 事件

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

属性 描述
onblur script 元素失去焦点时运行的脚本。
onchange script 在元素值被改变时运行的脚本。
oncontextmenu script 当上下文菜单被触发时运行的脚本。
onfocus script 当元素获得焦点时运行的脚本。
onformchange script 在表单改变时运行的脚本。
onforminput script 当表单获得用户输入时运行的脚本。
oninput script 当元素获得用户输入时运行的脚本。
oninvalid script 当元素无效时运行的脚本。
onreset script 当表单中的重置按钮被点击时触发。HTML5 中不支持。
onselect script 在元素中文本被选中后触发。
onsubmit script 在提交表单时触发。
2.3.4、Keyboard 事件
属性 描述
onkeydown script 在用户按下按键时触发。
onkeypress script 在用户敲击按钮时触发。
onkeyup script 当用户释放按键时触发。
2.3.5、Mouse 事件

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

属性 描述
onclick script 元素上发生鼠标点击时触发。
ondblclick script 元素上发生鼠标双击时触发。
ondrag script 元素被拖动时运行的脚本。
ondragend script 在拖动操作末端运行的脚本。
ondragenter script 当元素元素已被拖动到有效拖放区域时运行的脚本。
ondragleave script 当元素离开有效拖放目标时运行的脚本。
ondragover script 当元素在有效拖放目标上正在被拖动时运行的脚本。
ondragstart script 在拖动操作开端运行的脚本。
ondrop script 当被拖元素正在被拖放时运行的脚本。
onmousedown script 当元素上按下鼠标按钮时触发。
onmousemove script 当鼠标指针移动到元素上时触发。
onmouseout script 当鼠标指针移出元素时触发。
onmouseover script 当鼠标指针移动到元素上时触发。
onmouseup script 当在元素上释放鼠标按钮时触发。
onmousewheel script 当鼠标滚轮正在被滚动时运行的脚本。
onscroll script 当元素滚动条被滚动时运行的脚本。
2.3.6、Media 事件

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

属性 描述
onabort script 在退出时运行的脚本。
oncanplay script 当文件就绪可以开始播放时运行的脚本(缓冲已足够开始时)。
oncanplaythrough script 当媒介能够无需因缓冲而停止即可播放至结尾时运行的脚本。
ondurationchange script 当媒介长度改变时运行的脚本。
onemptied script 当发生故障并且文件突然不可用时运行的脚本(比如连接意外断开时)。
onended script 当媒介已到达结尾时运行的脚本(可发送类似“感谢观看”之类的消息)。
onerror script 当在文件加载期间发生错误时运行的脚本。
onloadeddata script 当媒介数据已加载时运行的脚本。
onloadedmetadata script 当元数据(比如分辨率和时长)被加载时运行的脚本。
onloadstart script 在文件开始加载且未实际加载任何数据前运行的脚本。
onpause script 当媒介被用户或程序暂停时运行的脚本。
onplay script 当媒介已就绪可以开始播放时运行的脚本。
onplaying script 当媒介已开始播放时运行的脚本。
onprogress script 当浏览器正在获取媒介数据时运行的脚本。
onratechange script 每当回放速率改变时运行的脚本(比如当用户切换到慢动作或快进模式)。
onreadystatechange script 每当就绪状态改变时运行的脚本(就绪状态监测媒介数据的状态)。
onseeked script 当 seeking 属性设置为 false(指示定位已结束)时运行的脚本。
onseeking script 当 seeking 属性设置为 true(指示定位是活动的)时运行的脚本。
onstalled script 在浏览器不论何种原因未能取回媒介数据时运行的脚本。
onsuspend script 在媒介数据完全加载之前不论何种原因终止取回媒介数据时运行的脚本。
ontimeupdate script 当播放位置改变时(比如当用户快进到媒介中一个不同的位置时)运行的脚本。
onvolumechange script 每当音量改变时(包括将音量设置为静音)时运行的脚本。
onwaiting script 当媒介已停止播放但打算继续播放时(比如当媒介暂停已缓冲更多数据)运行脚本

3、案例分析


<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>

深入浅出谈 iframe_第1张图片

可以看出,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对象。

深入浅出谈 iframe_第2张图片

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

6、同域/跨域

6.1、同域

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

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

6.2、跨域

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

深入浅出谈 iframe_第3张图片

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 http-equiv="Content-Security-Policy" content="child-src 'unsafe-inline' 'unsafe-eval' www.easonwong.com">
  • 或者通过HTTP头部信息加上Content-Security-Policy字段

你可能感兴趣的:(DAYNOTE,html,js,javascript,web)