在找到跨域解决办法之前,我们要先弄清楚一些基本概念

  • 什么是跨域?
  • 什么是“同源策略”?
  • 跨文档消息通信 & 跨域请求数据
  • 主域相同而子域不同
  • 不同域名的跨域访问

什么是跨域?

简单地理解就是因为同源策略的限制,a.com 域名下的js无法操作b.com或是xx.a.com域名下的对象。那么什么是“同源策略”?
 

什么是同源策略?

     源是在网络上用来建立信任关系的地址子集。源由规则(scheme)、主机(host)、端口(port)组成。例如,由于规则不同(如https与http),所以 http://www.a.com与 https://www.a.com页面的源是不同的。
(有关这部分的内容,特别推荐Rain Man大哥写的这一篇,非常清晰易懂:http://www.cnblogs.com/rainman/archive/2011/02/20/1959325.html
 
     同源策略是指:出于安全方面的考虑,运行在同一浏览器中的框架、标签页、窗口间的通信受到了严格的限制。源不同,则检索或修改其他源的内容时,浏览器会抛出安全异常,并阻止相应的操作。在html5 新的api出现以前,只有同源的页面才可以相互访问对象。 
 
其实跨域通信是分为两部分来讲的:
  • 跨文档消息通信 (如读取不同源页面的DOM对象等)
  • 跨域请求数据(跨域ajax请求, jsonp请求等)
注:实现跨域请求服务器数据 有很多种方式,如jsonp请求,flash等。本文主要讲“跨文档消息通信” 

跨文档消息通信

我们经常在工作中碰到的有两种:

  • 主域相同而子域不同

    可以通过设置document.domain+iframe的办法来解决

  • 不同域名的跨域访问

解决方案有很多,例如:

1. iframe+代理页+hash的方式

2. iframe + name

3. postMessage


下面我们用个例子来实现 “跨文档消息通信”

需求:a页面里有一个iframe(b页面)。当b页面加载完成后,同步一下iframe的高度。

1、“主域相同而子域不同” 的情况

下次上代码

2、“不同域名的跨域访问” 的情况

iframe+代理页+hash的方式:利用proxy.html代理页来实现. 这个办法比较绕,但是可以解决完全跨域情况下的脚步置换问题。原理是利用location.hash来进行传值原理及流程。来张我画的草图:

a页面,位于sport.taobao.com域名下

 <!DOCTYPE html>
<html>
<head>
<meta charset="gbk" />
<script src="http://a.tbcdn.cn/s/kissy/1.3.0/kissy-min.js"></script>
<style>
body{background:#00ae8f;}
.iframeArea{margin-top:30px;}
</style>
</head>
<body>
A:运动页面 此页面访问时的url是这样的:
http://sport.taobao.com/market/sports/a.php?iframeUrl=http://wanke.etao.com/mobile/product-600000000007215.html
<div class="iframeArea">
<iframe id="J_sport_iframe" name="sport_iframe" src="" frameborder="0" style="display: block; margin: 0 auto; height: 1000px;" width="990" scrolling="no" >
</iframe>
</div>
<script>
(function(S){
KISSY.use('uri',function(S,Uri){
var url = new Uri(location.href).getQuery().get('iframeUrl');
if(url){
S.all('#J_sport_iframe').attr("src",url); //给iframe赋src的值
}else{
S.all('#J_sport_iframe').attr("src","http://wanke.etao.com/error.html");
}
});
})(KISSY);
</script>
</body>
</html>

b页面位于wanke.etao.com域名下

<!DOCTYPE html>
<html>
<head>
<meta charset="gbk" />
<script src="http://a.tbcdn.cn/s/kissy/1.3.0/kissy-min.js"></script>
</head>
<body>
<div>
我是玩客页面:http://wanke.etao.com/mobile/product-600000000007215.html
</div>
<script>
/*
etao的B.html js 写在页面结束时
*/
(function (S) {
if (window != top) {
//在etao的页面B.html中创建iframe代理
S.one('body').append('<iframe id="iframeproxy" name="iframeproxy" src="" width="0" height="0" style="display:none;" ></iframe>'); function updateHeight() {
if (window !=top && S.one("#iframeproxy")) {
var ht = S.one("body").height() + 10, a = window.name, b;
b = "http://sport.taobao.com/market/sports/iframe-proxy2.php"
S.one("#iframeproxy")[0].src = b + "#" + ht;
}
}
updateHeight();
S.one(window).on('load', function () {
updateHeight();
});
}
})(KISSY);
</script>
</body>
</html>

proxy页面位于sport.taobao.com域名下,但是插入到b页面中

 <!DOCTYPE html>
<html>
<head>
<meta charset="gbk" />
<script src="http://a.tbcdn.cn/s/kissy/1.3.0/kissy-min.js"></script>
</head>
<body>
<script>
/*
taobao站点页面中的js http://sport.taobao.com/market/baobao/iframe-proxy2.php
*/
(function(S){
function pseth() {
var iObj = window.top.document.getElementById('J_sport_iframe');//A和iframe-proxy2同域,所以可以访问节点
iObjH = window.location.hash;//访问自己的location对象获取hash值
iObj.style.height = (+iObjH.split("#")[1]+5)+"px";//操作dom
}
pseth();
S.all(window).on("hashchange",function(){
pseth();
}); })(KISSY);
</script>
</body>
</html>

3. postMessage

  我这里有篇文章专门写postMessage做跨域的。请看 http://www.cnblogs.com/summer_shao/p/3998695.html

JavaScript跨域解决办法的更多相关文章

  1. JAVA联调接口跨域解决办法

    JAVA联调接口跨域解决办法 第一种代码: HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,HttpStatus. ...

  2. 关于iFrame特性总计和iFrame跨域解决办法

    1.iframe 定义和用法 iframe 元素会创建包含另外一个文档的内联框架(即行内框架). HTML 与 XHTML 之间的差异 在 HTML 4.1 Strict DTD 和 XHTML 1. ...

  3. JavaScript跨域解决方法大全

    跨域的定义:JavaScript出于安全性考虑,同源策略机制对跨域访问做了限制.域仅仅是通过“URL的首部”字符串进行识别,“URL的首部”指window.location.protocol +win ...

  4. javascript 跨域问题解决办法总结

    跨域的意思就是不同域名之间的页面默认是无法通信的.因为浏览器默认是禁止跨域的: 图所示:chrome浏览器尝试获取mainFrame失败,提示DomException 1).假如你有个网站 a.com ...

  5. JavaScript跨域解决方式

    平时工作中经常被JavaScript跨域问题所困扰,其实有很多种解决方式,下面给大家介绍常用的几种: 1.jsonp解决跨域问题 客户端代码: <!DOCTYPE html> <ht ...

  6. javascript 跨域请求详细分析(终极跨域解决办法)

    自从我接触前端以来,接手的项目里面很大部分都是前后端分离的,后端只提供接口,前端根据后端接口渲染出实际页面.个人觉得这是一个挺好的模式,前后端各自负责各自的模块,分工明确,而且也给前端更大的发挥空间. ...

  7. iFrame跨域解决办法

    按情境分1.不跨域时2.主域相同.子域不同时3.主域不同不跨域时访问iframe: contentWindow访问父级:parent访问顶级:top a.html <html xmlns=&qu ...

  8. ajax跨域解决办法

    在使用jquery的ajax作请求时,http://127.0.0.1:8080,类似这样的一个本地请求,会产生跨域问题, 解决办法一: jsonp: var url= "http://12 ...

  9. tornado django flask 跨域解决办法(cors)

    XMLHttpRequest cannot load http://www.baidu.com. No 'Access-Control-Allow-Origin' header is present ...

随机推荐

  1. Subline Text快捷键

    我经常使用的快捷键 Ctrl+A: 全选Ctrl+C: 复制 重复工作必备: Ctrl+D:选择单词,重复可增加选择下一个相同的单词Alt+F3:选择所有相同的词F3: 下一个Shift+F3:前一个 ...

  2. hdu4597Play Game(记忆化)

    链接 通化邀请赛的题 貌似不怎么难 记忆化DP 状态方程类似于2维的 只是变成了4维  每次有四种方向去搜 取最棒的 判断好边界条件 #include <iostream> #includ ...

  3. sql 不同server間寫入數據

    select * from sys.servers sp_dropserver @server =N'' sp_dropserver '' ,'droplogins' EXEC master.dbo. ...

  4. BZOJ_1180_[CROATIAN2009]_OTOCI_(LCT)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1180 三种操作: 1.询问x,y是否连通,如果不连通,建一条边x,y 2.把x节点的权值改为t ...

  5. MySQL海量数据查询优化策略

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  6. JS中的substring和substr函数的区别

    1. 在JS中, 函数声明: stringObject.substring(start,stop) start是在原字符串检索的开始位置,stop是检索的终止位置,返回结果中不包括stop所指字符. ...

  7. Jmeter:图形界面压力测试工具

    Jmeter是一款强大的图形界面压力测试工具,完全用Java写成,关于Jmeter的介绍,网上其实有不少的文章,我原本是不想再重复写类似文章的,但我发现有些很关键性的,在我们测试中一定会用到的一些设置 ...

  8. POJ 3342 (树形DP)

    题意 :给出一些上下级关系,要求i和i的直接上级不能同时出现,现在选出一些人构成一个集合,问你这个集合里面的最大人数是都少,同时给出这个最大的人数的集合是否唯一. 思路:树形DP,dp[i][0],表 ...

  9. HDU-1238 Substrings

    Substrings Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total ...

  10. Hadoop系列(一)hadoop2.2.0源码编译

    操作系统:Centos 所需条件:能上网 编译所需工具: apache-ant-1.9.2-bin.tar.gz apache-maven-3.0.5-bin.tar.gz findbugs-2.0. ...