Iframe简单探索以及Iframe跨域处理

探索Iframe

本文目的:

  • Iframe简单使用
  • Iframe跨域
  • Iframe常见问题

一.Iframe基本Dom以及常用属性和常用事件

1.DOM:

<iframe class="iframe" style="height: 100%;width: 100%;border: 0;"  id="Yiframe" name="Yiframe" src=‘http://localhost:2255/67iframe-2.html‘ ></iframe>

2.常用属性:

和平时使用的DOM标签类似,样式之类的还是建议用class吧,统一起来方便管理。

更多属性看:http://www.runoob.com/tags/ta...

3.常用事件:

<iframe> 标签支持 HTML 的事件属性

一般用这个就够了

onload:当文档加载时运行脚本

        document.querySelector(‘#Yiframe‘).onload = function(event){
            console.log(‘onload‘,event);
        }

二.JS动态新增并插入Iframe

和平时新增DOM标签一样即可。

var iframe = document.createElement(‘iframe‘);
     iframe.src = url;
     iframe.id = "Yiframe";
     iframe.style="height: 100%;width: 100%;border: 0;";
     $(‘.content‘).append(iframe);

三.iframe与父页面互动

1.注意事项

(1). 必须是在两者同域的情况下才能进行数据交互。

(2). 中间无论嵌套几次iframe,只要其中一个iframe与上级或者上上级同域,两者之前就能进行相互调用

2.实现方案(同域)

(1).父页面获取子页面

document.querySelector(‘#XXXX‘).contentWindow

window.frames[x]

可以获取到iframe内的window对象,包括iframe内自行声明的全局方法等。

window.frames注意事项:
  • 该属性返回窗口中所有命名的框架(<iframe>)。
  • 直接打印window.frames不是数组对象。
  • frames.length 来获取框架的数量。
  • 可以通过window.frames[数字]直接获取iframe内的window对象。

(2).子页面获取父页面

window.parent

可以获取到父页面的window对象,包括父页面内自行声明的全局方法等。

3.跨域(未跨主域)

(1).尝试。


打印 document.querySelector(‘#XXXX‘).contentWindow 和 window.parent 可以看到里面的属性和方法(第一层/第二层)。

但关键数据和方法会被和谐。

(2).修改document.domain实现跨域通信

网上搜到这个方法,但自己尝试的时候总会报错:

VM301:1 Uncaught DOMException: Failed to set the ‘domain‘ property on ‘Document‘: ‘baidu.com‘ is not a suffix of ‘corp.dinghuo123.com‘.
    at <anonymous>:1:17

因为同源安全政策不能直接修改。

首先补充一个知识点,然后再讲解怎么使用。

知识点:

一级域名 有的人叫根域名,如:dinghuo123.com、baidu.com、xx.com.cn、xx.cn.net 等等。

二级域名 是指增加了一级,包括www。如:www.dinghuo123.com、corp.dinghuo123.com、agent.dinghuo123.com 等等。所以有人把www.dinghuo123.com叫一级域名这是错误的。

document.domain 可以修改 corp.dinghuo123.com、agent.dinghuo123.com 为同一个主域 dinghuo123.com,此时即可通过上面步骤三-2实现父子之间的通信。

但是跨主域的时候就不能用这个方法了。

4.跨域(跨主域)

(1)方法

发送方:
otherWindow.postMessage(message, targetOrigin, [transfer]);

otherWindow

//其他窗口的一个引用,
//(1)比如iframe的contentWindow属性、
//(2)执行window.open返回的窗口对象、
//(3)或者是命名过或数值索引的window.frames。
//(4)父级parent.window对象

message

//将要发送到其他 window的数据。它将会被结构化克隆算法序列化。这意味着你可以不受什么限制的将数据对象安全的传送给目标窗口而无需自己序列化。
//PS个人觉得若是对象尽量还是自行序列化吧避免出现什么奇怪的问题。

targetOrigin

//通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串"*"(表示无限制)或者一个URI。在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配targetOrigin提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送。这个机制用来控制消息可以发送到哪些窗口;例如,当用postMessage传送密码时,这个参数就显得尤为重要,必须保证它的值与这条包含密码的信息的预期接受者的orign属性完全一致,来防止密码被恶意的第三方截获。如果你明确的知道消息应该发送到哪个窗口,那么请始终提供一个有确切值的targetOrigin,而不是*。不提供确切的目标将导致数据泄露到任何对数据感兴趣的恶意站点。
//PS简单来说就是*的话对方无论是什么URL都会触发onmessage回调,如果不是就会报错(图片见下方)

transfer //可选

//是一串和message 同时传递的 Transferable 对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。
//PS这个不是很懂,后面有时间研究。

targetOrigin报错图

postMessage兼容性

监听方:

window.onmessage = function(e){ console.log(e)}

e.source //可以获得父级window对象(必须是同域)
e.origin  //检查postMessage的发送页面的源。

(2)实践

父向子

//父:
document.querySelector(‘#xx‘).onclick = function(){
    window.frames[0].postMessage(‘testPost‘,‘*‘);
    //document.querySelector(‘#Yiframe‘).contentWindow.postMessage(‘testPost‘,‘*‘); 也可以
}
//子:
window.onmessage =function(e){
    console.log(‘onmessage2‘,e,document.domain);
} 

子向父

//子:
document.querySelector(‘#btn5‘).addEventListener(‘click‘,function(){
    parent.window.postMessage(‘testChildPost‘,‘*‘);
});

//父:
window.onmessage = function(e){
    console.log(‘onmessage父‘,e)
}

两个窗口:

理论上把window对象浏览器存储下再用上面的方式就能实现。未尝试。

(3)安全问题

如果您不希望从其他网站接收message,请不要为message事件添加任何事件侦听器。 这是一个完全万无一失的方式来避免安全问题。

如果您确实希望从其他网站接收message,请始终使用origin和source属性验证发件人的身份。 任何窗口(包括例如http://evil.example.com)都可以向任何其他窗口发送消息,并且您不能保证未知发件人不会发送恶意消息。 但是,验证身份后,您仍然应该始终验证接收到的消息的语法。 否则,您信任只发送受信任邮件的网站中的安全漏洞可能会在您的网站中打开跨网站脚本漏洞。

当您使用postMessage将数据发送到其他窗口时,始终指定精确的目标origin,而不是*。 恶意网站可以在您不知情的情况下更改窗口的位置,因此它可以拦截使用postMessage发送的数据。

四.路由变化以及前进后退。

  1. 控制台使用window.location.href会导致浏览器的url变化。
  2. 用户点击后退或者前进的时候,会根据之前的操作,完全依次复现(变化浏览器url和iframe内部页面路由变化)
  3. window.history.go(xx) 和 window.history.back() ,无论在父页面还是在子页面中,使用的效果和浏览器的前进后退是一样的。
  4. iframe中的页面使用window.location.href(和a标签)改变路由的时候不会引发浏览器url的变化,但会新增一条历史记录
  5. iframe每次重载,都会触发onload事件。

五.常见问题

  1. iframe内的路由变化,iframe的src值不会变!!!
  2. 要获取iframe内的当前url,用document.querySelector(‘#Yiframe‘).contentWindow.location.href;
  3. parent.window 在没有父级的时候 parent.window = window;

参考资料

SO JSON在线解析:http://www.sojson.com/blog/17...

浏览器同源政策: https://developer.mozilla.org...

postMessage:https://developer.mozilla.org...

原文地址:https://www.cnblogs.com/10yearsmanong/p/12223329.html

时间: 2024-10-08 04:39:21

Iframe简单探索以及Iframe跨域处理的相关文章

用iframe设置代理解决ajax跨域请求问题

面对ajax跨域请求的问题,想用代理的方式来解决这个跨域问题.在服务器端创建一个静态的代理页面,在客户端用iframe调用这个代理 今天在项目中需要做远程数据加载并渲染页面,直到开发阶段才意识到ajax跨域请求的问题.于是想用代理的方式来解决这个跨域问题. 什么是跨域?简单的来说,出于安全方面的考虑,页面中的JavaScript无法访问其他服务器上的数据,即"同源策略".而跨域就是通过某些手段来绕过同源策略限制,实现不同服务器之间通信的效果. 方案:在服务器端创建一个静态的代理页面,在

简单说说什么是跨域

目录 跨域警告的发生 补充: 如何允许跨域 CORS 简单请求的测试: 后端的处理 补充: 发表日期:2019年8月15日 跨域警告的发生 如果你做了一些前后端分离的项目,由于此时前端所在的服务地址与后端所在的服务地址不一样,你可能会遇到一个请求被浏览器拦截了的问题,浏览器在检测到当前页面发起的请求不属于当前域就会将其拦截,这是因为浏览器的"同源策略". 那么,什么是同源策略呢? 同源策略用于限制页面发起不同域(源)的请求,用于提高请求的安全性. 如果两个页面的协议.端口.IP地址(域

利用jsonp、iframe和location.hash解决跨域问题

几种解决js跨域的方法 js的跨域:由于浏览器同源策略,凡是发送请求url的协议.域名.端口三者之间任意一 与当前页面地址不同即为跨域.如下示例: URL 说明 是否允许通信 http://www.a.com/a.js http://www.a.com/b.js 同一域名下 允许 http://www.a.com/lab/a.js http://www.a.com/script/b.js 同一域名下不同文件夹 允许 http://www.a.com:8000/a.js http://www.a.

利用iframe+from表单实现跨域上传文件

一.需要的材料 客户端需要一个HTML页面A其中包含一个iframe和一个form表单,一个页面B(我称之为客户端代理)里面包含对返回参数的处理: 服务端需要一个asp.net的一般处理程序用来处理上传文件并返回值. 二.原理图 有图才有真相,哈哈哈 三.客户端代码实现 1.页面A的实现 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>A页面</ti

CSS完美实现iframe高度自适应(支持跨域)

Iframe的强大功能偶就不多说了,它不但被开发人员经常运用,而且黑客们也常常使用它,总之用过的人知道它的强大之处,但是Iframe有个致命的"BUG"就是iframe的高度无法自动适应,这一点让很多人都头疼万分.百度或是谷歌一下,确实很多解决方法,但尝试一下,会发现问题很多:浏览器兼容性差,不能自适应,仅支持同域Iframe等诸多问题,尤其是跨域Iframe高度自适应问题.网上根本找不到一种可行的方案(唯一有一种提到加入代理页面的,经过测试发现无用).难道真的没有一种可行的解决方案了

iframe中涉及父子页面跨域问题

什么是跨域? 跨域,指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器施加的安全限制.所谓同源是指相同的域名.协议和端口,只要其中一项不同就为跨域. 举几个例子: http://a.123.com/index.html和http://a.123.com/index.js非跨域,它们有相同的域名,协议和端口. http://a.123.com/index.html和http://b.123.com/index.js跨域,相同的端口.协议,但是域名不同(a.123.com和b

iframe子页面与父页面跨域相互访问方法

自己没事写着玩,要学习的比较多,先记录下来,以后慢慢修改! 1.先写同域情况下的iframe的父子调用 父窗口 1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title></title> 6 7 </head> 8 <body> 9 //父窗口 10 <iframe

iframe可通过postMessage解决跨域、跨窗口消息传递

https://www.cnblogs.com/dorothyorsusie/p/6178599.html 1 //iframe传参给父级页面 2 function give_info(){ 3 console.log("触发事件"); 4 window.parent.postMessage(1,'*'); 5 } //接收值window.addEventListener('message',function(e){ var color=e.data; document.getElem

Ajax接触及对跨域的简单理解

[Ajax]Ajax技术能够向服务器请求额外的数据而无须卸载页面能带来更好的用户体验.Ajax技术的核心是XMLHttpRequest对象(简称XHR),XHR向服务器发送请求和解析拂去其响应提供了流畅的接口.能够以异步方式从服务器取得更多信息,意味着用户单击后,可以不刷新页面也能取得新数据.也就是说,可以使用XHR对象取得新数据,然后再通过DOM将新数据插入到页面中.(这种技术就是无需刷新页面即可从服务器取得数据,被称为浏览器与服务器的通信) 在Ajax技术之前,网络世界是同步进行的,造成了很