iframe跨域javascript访问

来源:互联网 发布:淘宝金牌卖家 编辑:程序博客网 时间:2024/05/18 17:25
问题抽提主页A.html在域www.aaa.com中,要用Ifame嵌入在域www.bbb.com中的B.html网页。现在需要让B.html中进行某一操作之后,调用A.html中的js函数onExcute。如果进行一般的操作在B.html中使用"window.parent.onExcute();"调用根本不会被执行,也不提示错误,在调试时会得到"Permission denied to access property"的提示信息。如果是在同域的两个页面这么使用没有问题,但是在跨域环境下就会出现这样的情况,这就是所谓的“iframe跨域问题"。

在A.html中

 

<script type="text/javascript">function onExcute(wellStr){ //事件响应               }</script>  <iframe id="bFrameId" src="http://www.bbb.com/B.html" width="100%" height="100%"></iframe> 



在B.html中的某一事件响应函数中,需要调用A.html中onExcute(……)方法。 

 

问题分析:

(1)A.html与B.html跨域,在B.html使用window.parent.onExcute(……),会因跨域访问,受浏览器“强制”限制。

(2)网上很解决“iframe高度自适应”的解决方法,都通过B.html的window的location是可以公共访问的,location.hash用来存放需要需要传递的参数。但是本问题是方法调用,需要触发js函数的调用,而不仅仅是参数的获取。基于此也有极差的解决办法是,监测B.html中location.hash值的变化,在A.html中写一函数定时检测(如一秒钟)此值,一旦B.html中响应事件之后将参数放于location.hash中,那么A.html在周期内会检测到此值的变化。

(3)网上还有解决解决方法:其一是欺骗法,两个网页document.domain尽管不一样,可以强制使值一样为“aaa.com",以此达到欺骗IE的目的(其它浏览器不一定起效)。不适用于原因主页面使用大量的脚本框架,会影响其它部分功能的使用。其二是"同域iframe无限制“的方法,就是由于跨域脚本中对parent访问iframe的属性无限制。就是在B.html中再嵌入iframe(内容是来自与A.html同域的网页C.html),特别适用于解决高度自适应的问题(C.html可以直获取B.html的iframe宽高信息,而A.html与C.html是同域的,可以js函数调用不会受限)。

 但是,仍然无法实现事件的即时触发。

解决方案:结合以上两种方法(location.hash存储参数,同域iframe脚本调用无限制)

 

(1)在B.html中触发事件(例如函数btnEvent())中,修改C.html的location.href。其中的hash是url后面的从"#"开关的部分,用于存储参数,hash值的改变不影响iframe的刷新;而url后面的参数"redirected=true"用于修改url(实际上还是本页),主要用于触发cFrame重新加载(即C.html中的window.onload事件)

function btnEvent(){var str = 'well_1,well_2';//注意: frames获取C.html的frame时, cFrameId 是iframe的name属性//其中‘redirected=true’故意添加参数,强迫C.html的页面刷新,响应onload事件document.getElementById('cFrameId').setAttribute('src', 'http://www.aaa.com/C.html?redirected=true' + '#' + str);}<iframe id="cFrameId" name=' cFrame' src="http://www.aaa.com/C.html" style="display: none"></iframe>


 

(2)在C.html中,使用页面加载过程中响应事件,通过url的参数判断当前加载是否是B.html的操作引起的,如果是,则需要马上响应A.html中的onExcute()函数,然后需要再次刷新当前页,来恢复url中的无参状态,以保证B.html中通过修改url能够再次触发C.html刷新页面加载onload事件。

 

window.onload = function(){var url = window.location.href;if(url.indexOf('redirected=true') > -1){              var str= location.hash;      //以#开头的信息if(str.length > 1){str= str.substring(1);}window.parent.parent.onExcute(str);window.location.href = 'http://www.aaa.com/C.html';    //恢复状态,以方便B.html再次响应事件}}

 

总结:在B.html中能够调用A.html中的js函数的根本原因,是B.html能够控制其内嵌iframe(cFrame)的location,从而导致其内嵌iframe(因刷新页面)触发的onload事件。而从B.html传递的参数,则是通过url后缀加(以"#"开开头的)hash值来实现的,实际上,也可以不用hash,(既然用到了参数,何不用两个参数呢?)用两个url参数就可以,一个用来表示状态(如上面的"redirected=true"),一个用来传递B.html要调用A.html中js函数的参数(用来替换上面在url后面缀加hash值用来传参的方法)。同理,如果反过来,希望A.html调用B.html中的js函数,则需要通过修改bFrame(B.html所在的iframe)中location,来触发B.html的加载,在onload时通过url参数来判断是否该调用此B.html中的js函数。这样做可以解决这样的问题,但缺陷是B.html刷新太频繁,每次调用都需要刷新B.html两次。

原创粉丝点击