iframe标签
iframe一般用来包含别的页面,iframe标签元素会创建包含另外一个文档的内联框架。当我们需要在一个网页里,嵌套另外一个网页,或者广告等,就可以使用iframe。使用iframe的好处是,主页的css样式是不会影响到iframe里面的样式,它也不会影响主页CSS样式。一个页面可以有多个iframe,但是它能耗高。
在一个网页中的iframe标签是局部刷新,不会刷新整个页面。
iframe出现安全问题有两个方面,一个是你的网页被别人iframe,一个是你iframe别人的网页。
前端可以使用window.top来防止你的网页被iframe。
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;
}
后端服务器中X-Frame-Options相应头,主要是描述服务器的网页资源的iframe权限。
DENY:当前页面不能被嵌套iframe里,即便是在相同域名的页面中嵌套也不允许,也不允许网页中有嵌套iframe
SAMEORIGIN:iframe页面的地址只能为同源域名下的页面,只允许同源请求
ALLOW-FROM:可以在指定的origin url的iframe中加载,只允许指定网页的iframe请求
iframe标签的属性
src:规定在iframe标签中显示的文档的 URL,可以是页面地址也可以是图片,音频,视频的地址(必选)
width:框架作为一个普通元素的宽度,建议使用css设置(必选)
height:框架作为一个普通元素的高度,建议在使用css设置(必选)
scrolling:yes,no,auto(默认值)。规定是否在iframe标签中显示滚动条。
frameborder:1(默认值,就是显示边框),0(不显示边框)。规定是否显示 iframe标签周围的边框。
name:规定iframe的名称,可用于利用a标签的target来对应iframe的name以及通过window.frames[name]来获取iframe对象
allowtransparency:true or false,是否允许iframe设置为透明,默认为false
allowfullscreen:true or false,是否允许iframe全屏,默认为false
sandbox:用来给指定iframe设置一个沙盒模型限制iframe的权限
<iframe sandbox src=""></iframe>
这样会对iframe页面进行以下一系列的限制:
1.script脚本不能执行
不能发送ajax请求
不能使用本地存储,即localStorage,cookie等
不能创建新的弹窗和window
不能发送表单
不能加载额外插件比如flash等
常见的配置项:
<iframe sandbox="allow-forms allow-same-origin allow-scripts" src=""></iframe>
1.allow-forms:允许进行提交表单
2.allow-scripts:允许运行执行脚本
3.allow-same-origin:允许同域请求,比如ajax
4.allow-top-navigation:允许iframe能够主导window.top进行页面跳转
5.allow-popups:允许iframe中弹出新窗口,比如,window.open,target="_blank"
6.allow-pointer-lock:在iframe中可以锁定鼠标,主要和鼠标锁定有关
获取iframe里的内容
主要的两个就是contentWindow,和contentDocument iframe.contentWindow, 获取iframe的window对象 iframe.contentDocument, 获取iframe的document对象 这两个API只是DOM节点提供的方式(需要用DOM操作先获取iframe元素)
<body>
<iframe src="" frameborder="0" id="if"></iframe>
<script>
let iframe=document.getElementById("if");
let idocu=iframe.contentDocument;
console.log(iframe.contentWindow,11);
console.log(idocu);
console.log(window.frames["if"],222);
</script>
</body>
在iframe中获取父级内容
在同域下,父页面可以获取子iframe的内容,子iframe同样也能操作父页面内容。在iframe中,可以通过在window上挂载的几个API进行获取。
window.parent 获取上一级的window对象,如果还是iframe则是该iframe的window对象
window.top 获取最顶级容器的window对象,即,就是你打开页面的文档
window.self 返回自身window的引用。
iframe1.self === iframe1
iframe1.parent === iframe2
iframe2.parent === window
iframe1.top === window
iframe实现跨域请求
一般会使用iframe来进行父子页面的通信,对于主域相同子域不同的两个页面,我们可以通过document.domain + iframe来解决跨域请求问题。就是将某一方使用iframe嵌套在另一方页面
主域相同,不同子域之间的跨域请求 例如:http://www.aotu.com/a.html与http://sy.aotu.com/b.html
默认情况下document.domain是指window.location.hostname。可以手动更改,但是最多只能设置为主域名。通常,主域名就是指不带www的hostname,比如:aotu.com,baidu.com。 如果,带上www或者其他的前缀,就是二级域名或者多级域名。
iframe跨域的流程:b.html是以iframe的形式嵌套在a.html中
1.创建iframe,在a.html文件中,动态创建iframe元素
2.为了让用户无法看到这个iframe元素,需要使用CSS将其移出可视区或者允许设置为透明以及隐藏不可见
3 设置domain,为了保证a.html与b.html的访问都能够进行请求,需要为两个文件定义domain,即将document.domain设置为“主域名”。document.domain = aotu.com""指定相同的主域,然后两个文档就可以进行交互。
4 数据操作,在a.html文件当中获取b.html文件,就是动态创建的iframe元素获取它的window对象。就可以在a.html来操纵b.html
a.html
document.domain = "aotu.com";
let if = document.createElement('iframe');
if.src = "http://sy.aotu.com/b.html";
if.style.display = "none";
document.body.appendChild(if);
if.onload = function(){
let doc = if.contentDocument || if.contentWindow.document;
// 在这里操纵b.html
};
在b.html中同样设置document.domain = "aotu.com";