iframe标签的使用
Posted 前端卡夫卡
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iframe标签的使用相关的知识,希望对你有一定的参考价值。
iframe标签的使用
1、什么是iframe
- iframe是html元素,用于在网页中内嵌另一个网页。
- iframe默认有一个宽高,存在边界。
- iframe是一个行内块级元素,可以通过display修改。
- 所有浏览器都支持 iframe 标签。不过版本支持情况不同。
- 可以把需要的文本放置在 <iframe 和 </iframe 之间,这样就可以应对无法理解 iframe 的浏览器。
- 在 HTML 4.1 Strict DTD 和 XHTML 1.0 Strict DTD 中,不支持 iframe 元素。
-
-
iframe标签支持 HTML 中的全局属性:
-
iframe标签支持 HTML 中的事件属性:如Window 事件属性、Form 事件、Keyboard 事件、Mouse 事件、Media 事件等
-
2、iframe的元素属性
iframe常用的元素属性:
- src:指定内联网页的地址。
- width、height:控制iframe的宽高。
- frameborder:iframe默认有个边界,可以设置frameborder为0清除边界。
- name:框架的名称。
- scrolling:是否可滚动。yes、no、auto。
3、iframe操作
- 每个iframe里各自维护自己的全局window对象。
- 只有同域才能进行iframe之间的改写,跨域时,只能进行简单的路由跳转。
- 在父级使用window.frames[name]可以获取子iframe的window对象,相应的可以获取document对象,从而对子iframe进行dom操作。
- 在子iframe想要操作父元素的iframe,直接使用子元素的window.parent来获取父级元素的window对象,从而获取document来操作dom。
4、iframe 对象及属性
-
IFrame 对象代表 HTML iframe 元素。
-
可使用 getElementById() 来访问 iframe 元素。如:
var iframe = document.getElementById(“iframe”);
var iwindow = iframe.contentWindow;
var idoc = iwindow.document;等价于iframe.contentDocument;
(1)、获取iframe的iframe对象:console.log(“iframe”, iframe);
(2)、获取iframe的window对象:console.log(“window”, iwindow);
(3)、获取iframe的document:console.log(“document”, idoc);
(4)、获取iframe的html:console.log(“html”, idoc.documentElement);
(5)、获取head:console.log(“head”, idoc.head);
(6)、获取body:console.log(“body”, idoc.body);
-
在父级使用window.frames[name]结合iframe的Name属性可以获取子iframe的window对象,相应的可以获取document对象,从而对子iframe进行dom操作(更便捷)。如:
var iframes = window.frames;
var iframe = window.frames[‘myFrame’] // 返回的就是window对象(1)、console.log(“iframes”, iframes);
(2)、console.log(“iframe”, iframe),与下面相同。
(3)、获取iframe的window对象:console.log(“iframe”, iframe.window);
(4)、获取iframe的document:console.log(“document”, iframe.document)
-
在iframe中获取父级内容。
在同域下,父页面可以获取子iframe的内容,那么子iframe同样也能操作父页面内容。在iframe中,可以通过在window上挂载的几个API进行获取:
(1)、window.parent //获取上一级的window对象,如果还是iframe则是该iframe的window对象
(2)、window.top //获取最顶级容器的window对象,即,就是你打开页面的文档
(3)、window.self //返回自身window的引用。可以理解 window===window.self(脑残)
5、创建iframe元素
可使用 document.createElement() 方法来创建iframe元素:var x = document.createElement(“IFRAME”);
比如,iframe长轮询:
var iframeCon = docuemnt.querySelector('#container'),
text; //传递的信息
var iframe = document.createElement('iframe'),
iframe.id = "frame",
iframe.style = "display:none;",
iframe.name="polling",
iframe.src="target.html";
iframeCon.appendChild(iframe);
iframe.onload= function()
var iloc = iframe.contentWindow.location,
idoc = iframe.contentDocument;
setTimeout(function()
text = idoc.getElementsByTagName('body')[0].textContent;
console.log(text);
iloc.reload(); //刷新页面,再次获取信息,并且会触发onload函数
,2000);
6、iframe之间的通信
6.1、什么是主域名,什么是子域名(拓展)
- 主域名又称一级域名或者顶级域名,由域名主体 . 域名后缀组成,整个域名通常只有1个点号。 百度的主域名是baidu.com。
- 子域名一般会根据站点不同性质在主域名前面加上不同的前缀构成,通常比主域名多一个点或两个点。只要在主域名前面加上前缀的都是该主域名的子域名,子域名又能分为二级子域名、三级子域名、还有多级子域名。
- 例如:百度的二级域名(子域名)www.baidu.com 如1.www.baidu.com和2.www.baidu.com这样的三级域名也同样可以成为www.baidu.com和baidu.com的子域名。
- 拓展:子域名爆破就是指探测某个域名下的所有子域名。
6.2、iframe之间的通信
- iframe就是一个隔离沙盒,相当于我们在一个页面内可以操控很多个标签页一样。
- 浏览器判断你跨没跨域,主要根据两个点:一个是你网页的协议(protocol),另一个就是你的host是否相同(window.location.protocol、window.location.host)。
-
主域相同而子域不同,可以使用iframe进行解决document.domain = ‘’,指定相同的主域。比如在http://www.example.com/a.html和http://sub.example.com/b.html两个文件中都加上document.domain = “example.com”;
-
当我们要向指定iframe发送信息时,首先要获取该iframe自己的window对象,然后使用该window对象的postMessage发送消息。
- window.postMessage(message, targetOrigin, [transfer])
-
事件默认参数:
(1)、e.source – 消息源,消息的发送窗口/iframe。
(2)、e.origin – 消息源的 URI(可能包含协议、域名和端口),用来验证数据源。
(3)、e.data – 发送过来的数据。 -
使用注意点:
(1)、监听时使用window.addEventListener(“message”,(e)=>, false),必须保证监听的window和发送消息的window相同。
(2)、需要确定先监听了message事件,再发送的消息。
(3)、targetOrigin指定了URI的话,必须是相同的域和端口号,不然会报跨域错误。
(4)、targetOrigin使用*号的话,支持跨域,我们可以通过监听消息的默认参数e.origin来判断是否接收到了正确的消息。
(5)、当我们明确知道origin是谁时,不要使用星号,当要接受信息时,先判断origin是否是我们要接受的源,再做后续的操作。
(6)、获取子元素的document时要确保子元素所有dom元素已经挂载完毕,因此在原生的写法时,必须写在window的onload事件中。 -
iframe通信示例:
(1)、 窗口1:
- window.postMessage(message, targetOrigin, [transfer])
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>窗口1</div>
<iframe src="http://127.0.0.1:5501/2.html" frameborder="1" id='123' name="abc"></iframe>
<script>
window.onload = function ()
setTimeout(() =>
window.top.postMessage('handsome', '*')
, 0)
</script>
</body>
</html>
(2)、窗口2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>窗口2</div>
<script>
top.addEventListener('message',(e)=>console.log(e),false)
</script>
</body>
</html>
(3)、运行结果:
7、其他
7.1、iframe自适应
- iframe默认会自带滚动条,不会全屏。所以要想自适应的话首先去掉滚动条即在iframe标签上添加 scrolling=“no”。
<iframe scrolling="no" src="./aaa" id="iframe"></iframe>
- 设置iframe的高为body的高。
var iwindow = iframe.contentWindow; var idoc = iwindow.document; iframe.height = idoc.body.offsetHeight;
- 还可以添加其它的装饰属性。
- 示例:
// 可以直接写在内联里面,也可以在css里面定义,不过对于广告iframe来说,样式写在属性中,是最好的。 <iframe id="frame" name="frame" width="160" height="600" frameborder="0" src="target.html" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true"></iframe>
7.2、防嵌套网页
- iframe的使用会出现出现安全性,一共两个方面:一个是你的网页被别人iframe,另一个是你iframe别人的网页。
- 最出名的clickhacking就是使用iframe来 拦截click事件。因为iframe享有着click的最优先权,当有人在伪造的主页中进行点击的话,如果点在iframe上,则会默认是在操作iframe的页面。 所以,钓鱼网站就是使用这个技术,通过诱导用户进行点击。
7.2.1、浏览器端
- 前端可以使用window.top来防止你的网页被iframe。
- 限定你的网页不能嵌套在任意网页内。如果想要引用同域的框架的话,可以判断域名。
if(window != window.top) window.top.location.href = correctURL; // 判断域名 if(top.location.host != window.location.host) top.location.href = window.location.href; // 如果你网页不同域名的话,上述就会报错。可以使用try...catch...进行错误捕获。如果发生错误,则说明不同域,表示你的页面被盗用了。可能有些浏览器这样写是不会报错,所以需要降级处理再进行跳转即可。 try top.location.hostname; //检测是否出错 //如果没有出错,则降级处理 if (top.location.hostname != window.location.hostname) top.location.href =window.location.href; catch(e) top.location.href = window.location.href;
7.2.2、服务器端
- X-Frame-Options
- X-Frame-Options是一个相应头,主要是描述服务器的网页资源的iframe权限。目前的支持度是IE8+。有3个选项:
- X-Frame-Options: DENY。拒绝任何iframe的嵌套请求。
- X-Frame-Options: SAMEORIGIN。只允许同源请求。例如网页为 lgg.com/123.html,則 lgg.com 底下的所有网页可以嵌入此网页,但是 lgg.com 以外的网页不能嵌入
- X-Frame-Options: ALLOW-FROM。只允许指定网页的iframe请求,不过兼容性较差Chrome不支持
- X-Frame-Options其实就是将前端js对iframe的把控交给服务器来进行处理。
// 等价于X-Frame-Options: DENY if(window != window.top) window.top.location.href = window.location.href; // 等价于X-Frame-Options: SAMEORIGIN if(top.location.hostname != window.location.hostname) top.location.href =window.location.href;
- 该属性是对页面的iframe进行一个主要限制。另外还有一个Content Security Policy,同样也可以对iframe进行限制,而且,他应该是以后网页安全防护的主流。
- X-Frame-Options是一个相应头,主要是描述服务器的网页资源的iframe权限。目前的支持度是IE8+。有3个选项:
- sandbox
- sandbox是h5的一个新属性(IE10+支持),就是用来给指定iframe设置一个沙盒模型限制iframe的更多权限。
- 启用方式:添加sandbox属性。
<iframe sandbox src="..."></iframe>
- 会对iframe页面进行一系列的限制:
- script脚本不能执行。
- 不能发送ajax请求。
- 不能使用本地存储,即localStorage,cookie等。
- 不能创建新的弹窗和window。
- 不能发送表单。
- 不能加载额外插件比如flash等。
- 可以在sandbox里面进行一些设置:
<iframe sandbox="allow-forms allow-same-origin allow-scripts" src="..."></iframe>
7.3、iframe使用场景
- PDF文档预览。
- 插入广告等。
前端iframe标签介绍及使用
使用的场景:
(1) 有重复的板块内容显示的时候
# 后端如果是模板渲染方式(得到页面是通过继承的形式),可以换成iframe来请求直接获取子功能页面
iframe标签的作用:
iframe标签可以实现html主页面嵌套html子页面,子页面可以是一个功能页面,在某些时候使用iframe非常的方便
# 所以如果是模板渲染方式的,前端就可以使用iframe标签节省一点网络带宽(传输的内容会少一些,并且主页面不会刷新,只是iframe在请求得到新的资源)。
模板渲染和iframe的对比:
(1) 子页面通过继承的方式去实现,并且实现了html页面功能的拆分
不好的地方:通过继承,表示渲染模板时候,会先去加载继承的页面,再加载子页面,这样模板页面也会在网络传输,这样会占一些无用的带宽
使用iframe后:页面通过模板渲染,也仅是某个功能页面,返回的时候,会少返回模板继承的部分
(2) 菜单点击效果(主页面可能有多个菜单),要在后端提前去渲染好用户点的哪个菜单,才能返回给用户新的页面
不好的地方:增加了后端编码的复杂度,需要通过if判断把点击效果也加在标签上面,这样后端又会吃一些cpu的资源
使用iframe后:由于前端只是发送src请求(仅改变子页面内容),主页面不会改变,所以菜单只需写好前端事件即可,这样就会少后端很多模板渲染的麻烦事,可以少渲染一些内容,效率也会提升一点。
模板渲染比iframe这种方式好的地方:
(1) iframe是一个url显示的所有功能页面,模板渲染可以通过不同的url,来得到不同前端信息界面,而iframe这种方式能看见的url只有首页的url,所以用iframe的话,一般只会一个url去操作,如果要获取某个功能页面,首次打开也只能通过鼠标点击,才能请求到那个功能页面,但是效率来说肯定是iframe方式会高一点
iframe标签的使用:
注:
(1) 下面都是使用的jquery的写法定位的标签,和原生js查找不同
(2) 它俩之间的转换
jquery >>> dom === $(‘iframe‘)[0] : 关键是这个[0]
dom >>> jquery === $(dom定位到的标签)
格式:<iframe src=‘‘ frameborder=‘0‘></iframe>
属性:
src # 获取html页面的url网址
frameborder # 表示是否显示框架的边框,1显示,0不显示
1. iframe通过点击事件获取页面的写法
下面是点击搜索按钮的事件
# 这个是在iframe标签中场景,window.parent切换到父窗口
# 如果是在iframe外直接$(‘iframe‘).attr(‘src‘, new_url)即可
2. iframe的刷新页面及回退写法
# 先要找到iframe标签,在执行bom操作即可
(1) 在iframe标签中实现刷新
$(window.parent.document).find(‘iframe‘)[0].contentWindow.location.reload(true);
(2) 在iframe标签中实现回退
$(window.parent.document).find(‘iframe‘)[0].contentWindow.history.back();
(3) 主窗口的写法
$(‘iframe‘)[0].contentWindow.location.reload(true); $(‘iframe‘)[0].contentWindow.history.back();
3.获取iframe的当前url
注:如果在iframe中切换了子页面的url,通过src只会取到第一次的给的src属性
$(window.parent.document).find(‘iframe‘)[0].contentWindow.location.href;
4.主页面和iframe子页面互相调用函数
使用场景:
(1) 模态框的弹出,不能说你模态通过子页面的点击,仅在子页面有模态框的效果
(2) 各种消息弹框的显示,不能说在子页面显示,会错位
4.1.在iframe中调用主页面的内容
window.parent.要调用的函数();
例子写法:
# 父页面中
# iframe中
4.2.主页面调用iframe的内容(没有试验)
$(‘iframe‘)[0].contentWindow.要调用的函数();
以上是关于iframe标签的使用的主要内容,如果未能解决你的问题,请参考以下文章