JS iframe 跨域

摘要:
转自:wujiajun1020方案一、剪贴板原理:IE本身依附于windows平台的特性为我们提供了一种基于iframe,利用内存来“绕行”的方案,在这里我称之为,本地存储原理。并且当在一个页面中还包含有其它的iframe时,会产生安全性异常,拒绝访问。

转自:wujiajun1020

方案一、剪贴板

原理:IE本身依附于windows平台的特性为我们提供了一种基于iframe,利用内存来“绕行”的方案,在这里我称之为,本地存储原理。

缺点:不支持非IE浏览器,并且影响到用户对剪贴板的操作,用户体验非常不好,特别是在IE7下,受安全等级影响,会弹出提示框。


子页面在子域:demo.ioldfish.cn下,在页面中加入如下代码获取页面高度并存入剪贴板。

  1. <scripttype="text/javascript">
  2. varua=navigator.userAgent;
  3. if((i=ua.indexOf("MSIE"))>=0)
  4. {
  5. variObjH=window.document.documentElement.scrollHeight;
  6. window.clipboardData.setData('text',String(iObjH));
  7. }
  8. </script>

主页面在主域:www.ioldfish.cn下,在页面中加入如下代码,获取剪贴板的值并赋值为子页面所在的iframe的高度。

  1. <scripttype="text/javascript">
  2. window.onload=function()
  3. {
  4. variObj=document.getElementById('iId');
  5. iObj.style.height=parseInt(window.clipboardData.getData('text'))+'px';
  6. }
  7. </script>

方案二、document.domain

原理:设置了document.domain,欺骗浏览器

缺点:无法实现不同主域之间的通讯。并且当在一个页面中还包含有其它的iframe时,会产生安全性异常,拒绝访问。

主页面在主域:www.ioldfish.cn下,子页面在子域:demo.ioldfish.cn下,在两个页面的头部都加入如下代码:

  1. <scripttype="text/javascript">
  2. document.domain="ioldfish.cn";
  3. </script>

方案三、通过JS获取hash值实现通讯

原理:hash可以实现跨域传值实现跨域通讯。

缺点:对于父窗口URL参数动态生成的,处理过程比较复杂一些。并且IE之外的浏览器遇到hash的改变会记录历史,影响浏览器的前进后退功能,体验不佳。


子页面在主域:www.lzdaily.com下,在页面中添加如下代码,因为hash是不受跨域限制的,所以可以将本页面的高度顺利的传送给主页面的hash。

  1. <scripttype="text/javascript">
  2. varhashH=document.documentElement.scrollHeight;
  3. varurlA="http://www.ioldfish.cn/wp-content/demo/domain/hash/a2.html";
  4. parent.location.href=urlA+"#"+hashH;
  5. </script>

主页面在主域:www.ioldfish.cn下,在页面中添加如下代码,首先取得子页面传递过来的hash值,然后将hash值赋到子页面所在的iframe的高度上。

  1. <scripttype="text/javascript">
  2. window.onload=function()
  3. {
  4. variObj=document.getElementById('iId');
  5. if(location.hash)
  6. {
  7. iObj.style.height=location.hash.split("#")[1]+"px";
  8. }
  9. }
  10. </script>

方案四、传hash值实现通讯改良版

原理:该方案通过“前端代理”的方式,实现hash的传值,体验上比之方案三有了很大的提升。

缺点:对于父窗口URL参数动态生成的,处理过程比较复杂一些。

子页面在主域:www.lzdaily.com下,在页面中添加如下代码,首先在页面里添加一个和主页面同域的iframe[也可动态生成],他的作用就像是个跳板。C页面中不需任何代码,只要确保有个页面就防止404错误就可以了!该方法通过修改iframe的name值同样可以跨域传值,只是比较”猥琐“而已。

  1. <iframeid="iframeC"name="iframeC"src="http://www.ioldfish.cn/wp-content/demo/domain/hashbetter/c.html"frameborder="0"height="0"></iframe>

然后在页面中加上如下代码,利用页面C的URL接收hash值,并负责把hash值传给同域下的主页面。

  1. <scripttype="text/javascript">
  2. hashH=document.documentElement.scrollHeight;
  3. urlC="http://www.ioldfish.cn/wp-content/demo/domain/hashbetter/c.html";
  4. document.getElementById("iframeC").src=urlC+"#"+hashH;
  5. </script>

主页面在主域:www.ioldfish.cn下,在页面中添加如下代码,获取从C页面中传递过来的hash值。这里应用到一个技巧,就是直接从A页面用frames["iId"].frames["iframeC"].location.hash,可以直接访问并获取C页面的hash值。这样一来,通过代理页面传递hash值,比起方案三,大大提高了用户体验。

  1. <scripttype="text/javascript">
  2. window.onload=function()
  3. {
  4. variObj=document.getElementById('iId');
  5. iObjH=frames["iId"].frames["iframeC"].location.hash;
  6. iObj.style.height=iObjH.split("#")[1]+"px";
  7. }
  8. </script>

方案五、JSONP

原理:有点脚本注入的味道

缺点:服务器端程序运行比脚本早,跨域交互时无法捕获前端页面元素的相关数据,比如自适应高度。


主页面在主域:www.ioldfish.cn下,在页面中添加如下代码,动态创建一个script,然后指定到子域的动态文件,在动态文件后面可以添加参数,在这里我加了一个回调函数,当请求返回后,会运行这个回调函数。

1. <script type="text/javascript">
2. function loadContent()
3. {
4. var scriptDom=document.createElement('script');
5. var url = "http://www.lzdaily.com/domain/jsonp/Test.aspx?f=setDivContent'";
6. scriptDom.src= url;
7. document.body.appendChild(scriptDom);
8. }
9. function setDivContent(love)
10. {
11. var fishDiv = document.getElementById("oldFish");
12. fishDiv.innerHTML = love;
13. }
14. </script>

子页面在主域:www.lzdaily.com下,在页面中添加如下代码,首先先取得主页面传过来的回调函数名,然后生成一段 javascript代码,以回

调函数带参数的形式返回主页面,这样就完成了跨域之间的通讯。由于服务器端程序执行总是优先于javascript代码,所以基本上没办法获取

到子页面中DOM的相关数据,所以小白同学,我可以很负责人的告诉你,想通过这种方法实现跨域自适应高度是不可能的!

1. <script language="C#" runat="server">
2. void Page_Load(object sender, EventArgs e)
3. {
4. string f = Request.QueryString["f"];
5. Response.Clear();
6. Response.ContentType = "application/x-javascript";
7. Response.Write(String.Format(@"{0}({1});", f,1122));
8. Response.End();
9. }
10. </script>

方案六、window.name

原理:window.name本身并不能实现跨域,只是中间做了代理。

缺点:获取异域的前端页面元素值有一定局限性,比如取自适应高度的值。但是此方法在前端页面元素的数据交互上明显比JSONP强。
这个方案,YAHOO的同事已经给出了详细的demo,我就不重复了,演示demo出自YAHOO克军之手。详细的说明可以参看“怿飞的BLOG”,个人觉

得方案四比window.name适用面更广一些。


方案七、window.navigator

原理:window.navigator这个对象是在所有的Iframe中均可以访问的对象。应该是IE的一个漏洞!
缺点:不支持IE外的浏览器下的跨域。严格的dtd申明后,该方法失效!

主页面在主域:www.ioldfish.cn下,首先先申明一个Json用来保存所有页面的高度window.navigator.PagesHeight={”":0};,然后根据name

的属性找到页面的数据window.navigator.getData,最后将页面的数据注册到window.navigator.PagesHeight中。这里还定义了一个函数

resetIframeData,在页面加载的时候调用它,完成跨域的数据交互。注释中详细说明了参数的作用。

1. <script type="text/javascript">
2. window.navigator.PagesHeight={"":0};
3. window.navigator.getData=function(pageName) {
4. return window.navigator.PagesHeight[pageName];
5. };
6. window.navigator.putData=function(pageName,pageHeight)
7. {
8. window.navigator.PagesHeight[pageName]=pageHeight;
9. };

1. /*
2. *iframeId:页面中iframe的标识id
3. *key:子页面自定义的json标识,这里就是子页面定义的"PortalData".
4. *defaultData:无法取到值时候调用
5. */
6. function resetIframeData(iframeId,key,defualtData)
7. {
8. var obj=document.getElementById(iframeId);
9. if(window.navigator.getData)
10. {
11. var pageHeight = window.navigator.getData(key);
12. if(pageHeight && String(pageHeight).match(/\d+/))
13. {
14. obj.style.height=pageHeight+'px';
15. }
16. else
17. {
18. obj.style.height=defualtData + 'px';
19. }
20. }
21. else
22. {
23. obj.style.height=defualtData + 'px';
24. }
25. }
26. </script>

子页面在主域:www.lzdaily.com下,获取到页面高度后,将高度存到主页定义的Json中,Json标识为”PortalData”,这里可以自定义。

1. <script type="text/javascript">
2. window.onload = function getPageData()
3. {
4. var pageHeight = document.body.scrollHeight;
5. if(window.navigator.putData)
6. {
7. window.navigator.putData("PortalData",pageHeight);
8. }
9. }
10. </script>

其实通过css也可以实现跨域,数据获取的实质其实就是动态载入一段CSS,然后解析其中的字段提取数据,这个方法比较“猥琐”,再这里就

不多介绍了

免责声明:文章转载自《JS iframe 跨域》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇idea+html图片加载失败H3C路由交换常用命令下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

面渣逆袭:HashMap追魂二十三问

大家好,我是老三。 HashMap作为我们熟悉的一种集合,可以说是面试必考题。简单的使用,再到原理、数据结构,还可以延伸到并发,可以说,就一个HashMap,能聊半个小时。 1.能说一下HashMap的数据结构吗? JDK1.7的数据结构是数组+链表,JDK1.7还有人在用?不会吧…… 说一下JDK1.8的数据结构吧: JDK1.8的数据结构是数组+链表+...

js中iframe的用法

最近遇到的项目总是习惯左边一个树,点击每个树的节点右边出现相应的信息,遇到这种情况用iframe还是很简单的, 例如 : 页面文件 1 @section Tree{ 2 <ul id="tree"> 3 </ul> 4 5 } 6 @section Search 7 { 8 } 9 <i...

JS散度(Jensen-Shannon)

JS散度相似度衡量指标。 https://blog.csdn.net/wateryouyo/article/details/52831115 https://blog.csdn.net/FrankieHello/article/details/80614422?utm_source=copy  KL散度、JS散度和交叉熵 三者都是用来衡量两个概率分布之间的...

js获取url中指定参数的值(含带hash)

function getUrlVars() { var vars = {}; var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (m, key, value) {...

用户密码加密存储十问十答,一文说透密码安全存储

我们数据库的权限管理十分严格,敏感信息开发工程师都看不到,密码明文存储不行吗? 不行。存储在数据库的数据面临很多威胁,有应用程序层面、数据库层面的、操作系统层面的、机房层面的、员工层面的,想做到百分百不被黑客窃取,非常困难。 如果密码是加密之后再存储,那么即便被拖库,黑客也难以获取用户的明文密码。可以说,密码加密存储是用户账户系统的底裤,它的重要性,相当于...

[ligerUI] grid行编辑示例

ligerui grid行编辑示例,具备新增行、删除行功能,可在修改某个cell之后,如果录入错误,可以提醒用户。 <%@ page contentType="text/html; charset=UTF-8" %> <% String path = request.getContextPath(); %> <!DOC...