在平时的开发中,或多或少会用到iframe,大部分时候咱们只须要简单的使用iframe标签,设置个宽高便可,不多回去深究iframe的别的特性。好比这种用法:html
<iframe src='https://blog.5udou.cn'>
复制代码
但直到产品经理要求说,iframe嵌入的页面可不可让主页面的url地址发生变化呀?好吧,一会儿懵圈了,我得去查查资料,因而索性就深究深究iframe的一些特性,省得再次尴尬。git
下面全部代码均可以在这里找到:github.com/linxiaowu66…github
iframe的特性都是依赖参数配置实现的,现整理以下有用的属性:web
属性 | 解释 | 备注 |
---|---|---|
allow | 能够为iframe指定特性策略 | |
allowfullscreen | 是否容许iframe调用requestFullscreen()方法激活全屏模式,这个属性等同于allow属性的这个配置:allow="fullscreen" |
|
allowpaymentrequest | 是否容许一个跨域的iframe调用支付请求API | |
csp | 内嵌的资源强制实行同源策略 | |
height | iframe的高度,默认150px | |
importance | 标识在iframe属性src指示的资源的下载优先级,有auto /high /low 三个等级 |
|
name | 内嵌的浏览内容的目标名称 | |
referrerpolicy | 指示当获取frame的资源的时候携带的referrer,默认是no-referrer-when-downgrade ,也就是仅当发生协议降级(如 HTTPS 页面引入 HTTP 资源,从 HTTPS 页面跳到 HTTP 等)时不发送 Referrer 信息。这个规则是如今大部分浏览器默认所采用的; |
|
sandbox | 在frame上的内容上运用额外的一下限制,具体哪些字段咱们下面详细解释 |
allow属性的使用须要参考特性策略这一小节。特性策略能够容许你控制页面或者iframe可使用哪些特性。页面控制的话设置在HTTP头部的Feature-Policy的这个字段,iframe的话就是咱们要说的这个allow字段。跨域
特性策略的书写规则是:<feature name> <allowlist of origin(s)>
数组
完整的特性名称参考: Policy Controlled Features或者Feature-Policy 浏览器
而allowlist则有以下规则:安全
*
:表示该特性在该文档下都是容许的,包括全部的嵌套的浏览内容(iframes),而不用管这些内容的源。self
:表示该特性在该文档下都是容许的,而且仅在同源的状况下嵌套的浏览内容(iframes)才可使用。src
:(iframes的allow属性专用)表示该特性在这个iframe下容许使用,只要加载的文档来源的源和iframe的src
属性指定的URL是同源的。none
:表示该特性在顶层以及嵌套的浏览内容下都是被禁用的<origin(s)>
:表示该特性只在一些指定的源下才容许使用,多个源使用空格隔开今天咱们主要讲一下iframe下的allow属性,好比你不容许iframe的页面全屏、不容许调用摄像头之类的行为,能够这么配置:bash
<iframe allow="camera 'none'; fullscreen 'none'">
app
好比只容许同源的才可使用全屏这个特性:
<iframe src="https://example.com..." allow="fullscreen 'src'"></iframe>
好比只容许指定源才可使用定位功能:
<iframe src="https://google-developers.appspot.com/demos/..." allow="geolocation https://google-developers.appspot.com"></iframe>
这个属性牵扯到了HTTP的referer策略,咱们知道referer的策略是这样的:
好比咱们这样配置:
<iframe allow="fullscreen 'none'" referrerpolicy="no-referrer" src='http://127.0.0.1:3000/iframe.html'></iframe>
复制代码
咱们经过抓包能够看到对应的请求是这样的:
iframe的沙箱模式能够提供一些额外的配置,当你把一个iframe置为沙箱的时候,意味着沙箱内的内容的行为全凭你控制了。
好比你在iframe下这样配置:
<iframe sandbox="" src='http://127.0.0.1:3000/iframe1.html'></iframe>
可是iframe1.html中却有对应的js脚本,那么在控制台下能够看到这样的报错:
Blocked script execution in 'http://127.0.0.1:3000/iframe1.html' because the document's frame is sandboxed and the 'allow-scripts' permission is not set. 复制代码
因此当你的iframe有脚本的时候,基本上都会配置allow-scripts
这个属性。
再好比你的页面会有form标签提交数据的时候,若是没有allow-forms
,则会报这种错误:
Blocked form submission to '' because the form's frame is sandboxed and the 'allow-forms' permission is not set. 复制代码
接下来解释一下各个配置的含义:
属性 | 解释 |
---|---|
allow-forms | 容许资源提交表单 |
allow-modals | 容许资源打开模态窗口,好比window.alert()、window.confirm()、window.print()、window.prompt() |
allow-orientation-lock | 容许资源锁住屏幕方向 |
allow-pointer-lock | 容许资源使用Pointer Lock API |
allow-popups | 容许弹出窗口(好比window.open(), target="_blank", 或者showModalDialog()),若是这个关键词没有的话,弹出窗口将会静默地打开失败 |
allow-popups-to-escape-sandbox | 容许沙箱文档打开新窗口,而这些新窗口不须要继承沙箱模式。 |
allow-presentation | 容许嵌入者控制是否iframe启用一个展现会话 |
allow-same-origin | 容许将内容做为普通来源对待。若是未使用该关键字,嵌入的内容将被视为一个独立的源。 |
allow-scripts | 容许嵌入的浏览上下文运行脚本(但不能建立弹窗) |
allow-top-navigation | 容许嵌入的页面的上下文能够导航(加载)内容到顶级的浏览上下文环境(browsing context)。若是未使用该关键字,这个操做将不可用 |
allow-storage-access-by-user-activation | 容许嵌入的页面请求经过Storage Access API使用父页面的存储能力 |
allow-top-navigation-by-user-activation | 容许嵌入的页面的上下文能够导航(加载)内容到顶级的浏览上下文环境(browsing context),可是只能经过用户手势主动调用来初始化 |
关于沙箱模式的注意点
allow-scripts
和allow-same-origin
,不然的话将容许嵌入的文档经过代码删除sandbox
属性。虽然你能够这么作,可是这样的话其安全性还不如不用sandbox。通过上面的解释,想必知道刚开始的那个问题的答案了吧?
frames属性是一个相似数组的对象;由于frames其实是window对象的别名,frames属性又是能够遍历的,因此它是一个相似数组的对象: window.frames.length === window.length;
frames属性的每一项是框架内的窗口,即框架内的window对象;frames属性的每一项并非iframe的dom节点!!!若须要获取iframe的dom节点能够经过如下方法: frames[0].frameElement
若是有一个iframe是处于沙箱模式,而且没有设置allow-same-origin
,那么虽然你能够访问到window.frames的长度为2,可是当你获取window.frames[1].location的时候会有这样的错误:
DOMException: Blocked a frame with origin "http://127.0.0.1:3000" from accessing a cross-origin frame
配置了allow-same-origin
的时候:
没有配置allow-same-origin
的时候:
window.top: 顶层窗口,即最上层的窗口
window.parent: 父窗口,若是一个窗口没有父窗口,则它的parent属性为自身的引用;
window.self: 当前窗口,即自身的引用;