感觉文章写的不错,虽然好些还是看不懂,先收藏
原文地址:http://truemylife.iteye.com/blog/1454300
一、源
同源策略是浏览器都必须遵循的策略,这就限制了js去调用和修改非同域下的数据。试想如果没有这个策略,在另外一个域的js就能轻易修改当前你正在调用的页面。那就天下大乱,毫无安全可言了。遵循同源策略就对非同域的资源调用加上了许多限制。我们知道css、image、及js本身(指文件本身)是可以跨域引用的。但html文件和js具体的数据调用如ajax是不能跨域了。还有,所谓同源是指两个页面的协议、域名、端口完全相同,否则都算跨域。通常我们会有很多二级域名,这时需要设置document.domain与主域名一致,否则也认为是跨域。
二、典型的资源共享案例
1)、html做为模板,想被各系统共用。(主次域名)
2)、公开的数据接口想被各系统调用。(不同域名)
3)、请求第三方url结果。(不同域名)
这里先列出这三种需求,因为不同的需求,技术选型也不一样。
三、Cross-Origin Resource Sharing
这是W3C推出的跨域资源标准规范,其核心部分是通过HTTP请求头来控制跨域的安全性,主要有两个头描述,一是Origin:描述当前的资源是可用来跨域请求的;另外一个是Access-Control-Allow-Orgin:用来描述哪些域是可以访问该资源,允许设置多个。
由于IE8之前的版本及其他浏览器稍低些的版本不遵循此规范,从当前来看其应用还不广泛,因此暂不考虑用此方案来解决上述三个案例。如要对Cross-Origin Resource Sharing进官方进一步了解:http://www.w3.org/TR/cors/。
四、跨域请求资源方案
1、配置反向代理
比如你的资源在ip/resource/resource.html下,中间件只配置resource目录给resource.caidao8.com。现在 有www.caidao8.com、practise.caidao8.com都想跨域调用resource.html。可以通过配置中间件,把ip/resource目录同时配置到域resource.caidao8.com、www.caidao8.com下。这样在resource.caidao8.com要调用resource.html时,就直接这样引用http://resource.caidao8.com/resource/resource.html,同样的在www.caidao8.com要调用时这样引用http://www.caidao8.com/resource/resource.html。实际上如果你有其他不同的域,比如www.caidao8.cn,也可以把资源配置一份到www.caidao8.cn域下。就看你拥有几个域并配置它们。
结论:通过中间件配置让共用资源变成多种域名下可访问是解决跨域的一种有效方法。但方案受限于共享的资源完全由自己控制。还有像tomcat、jetty本身一般不做反向代理,如果要在开发环境查看效果和调试,就得给开发环境也安装Nginx/apache,这增加了开发环境的复杂性,考虑到整个团队实施问题,在实际中我们团队没有采用这种方案。
2、IFrame解决跨域问题及其不足之处
IFrame解决跨域问题,只限于a、b是主次域名,首先设置document.domain使主次域名统一。我们设定a是parent,b是放在a下的iframe源。首先在b页面加上一段
<script>$(document).attr(“domain”,”caidao8.com”);</script>(本文所有js代码以jquery表示)。在a下编写js代码:
@H_301_119@
- $jq(document).attr("domain","caidao8.com");
- //jquery找不到object,会自动创建此对象
- $jq("<iframeid='dddiframe'></iframe>").attr("src","http://testresource.caidao8.com/billtemplate/aaa.html").appendTo("body");
- //后续事件必须等iframe资源加载完成后才能操作,而不同的浏览器对iframe资源是否加载完成事件不一致
- //iframe下使用jquery的bind与javascript原意attachEvent,两者执行顺序不同,使用jquerybind绑定未果,采用jsDom对象来操作
- variframe=$jq("#dddiframe")[0];
- if(iframe.attachEvent){//解决ie不认iframeonload问题
- iframe.attachEvent("onload",function(){
- alert($jq("#dddiframe").contents().find("#billid").html());
- });
- }else{
- iframe.onload=function(){
- //FF及Chrome能正常获取
- alert($jq("#dddiframe").contents().find("body").html());
- };
- }