web开发教程之跨域的解决方案详解

所属分类: 网页制作 / 应用技巧 阅读数: 496
收藏 0 赞 0 分享

前言

本文主要给大家介绍了关于web开发之跨域的解决方案,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。

什么是跨域?

概念如下:只要协议、域名、端口有任何一个不同,都被当作是不同的域

下面是具体的跨域情况详解

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.com/b.js 同一域名,不同端口 不允许
http://www.a.com/a.js、https://www.a.com/b.js 同一域名,不同协议 不允许
http://www.a.com/a.js、http://70.32.92.74/b.js 域名和域名对应ip 不允许
http://www.a.com/a.js、http://script.a.com/b.js 主域相同,子域不同 不允许(cookie这种情况下也不允许访问)
http://www.a.com/a.js、http://a.com/b.js 同一域名,不同二级域名(同上) 不允许(cookie这种情况下也不允许访问)
http://www.cnblogs.com/a.js、http://www.a.com/b.js 不同域名 不允许

一、document.domain跨域

原理:相同主域名不同子域名下的页面,可以设置document.domain让它们同域

限制:同域document提供的是页面间的互操作,需要载入iframe页面

下面几个域名下的页面都是可以通过document.domain跨域互操作的: http://a.com/foo, http://b.a.com/bar, http://c.a.com/bar。 但只能以页面嵌套的方式来进行页面互操作,比如常见的iframe方式就可以完成页面嵌套

// URL http://a.com/foo
var ifr = document.createElement('iframe');
ifr.src = 'http://b.a.com/bar'; 
ifr.onload = function(){
    var ifrdoc = ifr.contentDocument || ifr.contentWindow.document;
    ifrdoc.getElementsById("foo").innerHTML);
};
ifr.style.display = 'none';
document.body.appendChild(ifr);

上述代码所在的URL是http://a.com/foo,它对http://b.a.com/bar的DOM访问要求后者将 document.domain往上设置一级

// URL http://b.a.com/bar
document.domain = 'a.com'

document.domain只能从子域设置到主域,往下设置以及往其他域名设置都是不允许的, 在Chrome中给出的错误是这样的

Uncaught DOMException: Failed to set the 'domain' property on 'Document': 'baidu.com' is not a suffix of 'b.a.com'

二、有src的标签

原理:所有具有src属性的HTML标签都是可以跨域的,包括<img>, <script>

限制:需要创建一个DOM对象,只能用于GET方法

document.body中append一个具有src属性的HTML标签, src属性值指向的URL会以GET方法被访问,该访问是可以跨域的

其实样式表的<link>标签也是可以跨域的,只要是有src或href的HTML标签都有跨域的能力

不同的HTML标签发送HTTP请求的时机不同,例如<img>在更改src属性时就会发送请求,而script, iframe, link[rel=stylesheet]只有在添加到DOM树之后才会发送HTTP请求:

var img = new Image();
img.src = 'http://some/picture';        // 发送HTTP请求
var ifr = $('<iframe>', {src: 'http://b.a.com/bar'});
$('body').append(ifr);                  // 发送HTTP请求

三、JSONP

原理:<script>是可以跨域的,而且在跨域脚本中可以直接回调当前脚本的函数

限制:需要创建一个DOM对象并且添加到DOM树,只能用于GET方法

JSONP利用的是<script>可以跨域的特性,跨域URL返回的脚本不仅包含数据,还包含一个回调

// URL: http://b.a.com/foo
var data = {
    foo: 'bar',
    bar: 'foo'
};
callback(data);

然后在我们在主站http://a.com中,可以这样来跨域获取http://b.a.com的数据:

// URL: http://a.com/foo
var callback = function(data){
    // 处理跨域请求得到的数据
};
var script = $('<script>', {src: 'http://b.a.com/bar'});
$('body').append(script);

其实jQuery已经封装了JSONP的使用,我们可以这样来

$.getJSON( "http://b.a.com/bar?callback=callback", function( data ){
    // 处理跨域请求得到的数据
});

$.getJSON与$.get的区别是前者会把responseText转换为JSON,而且当URL具有callback参数时, jQuery将会把它解释为一个JSONP请求,创建一个<script>标签来完成该请求

四、navigation 对象

原理:iframe之间是共享navigator对象的,用它来传递信息

要求:IE6/7

有些人注意到了IE6/7的一个漏洞:iframe之间的window.navigator对象是共享的。 我们可以把它作为一个Messenger,通过它来传递信息。比如一个简单的委托:

// a.com
navigation.onData(){
    // 数据到达的处理函数
}
typeof navigation.getData === 'function' 
    || navigation.getData()
// b.com
navigation.getData = function(){
    $.get('/path/under/b.com')
        .success(function(data){
            typeof navigation.onData === 'function'
                || navigation.onData(data)
        });
}

document.navigator类似,window.name也是当前窗口所有页面所共享的。也可以用它来传递信息。 同样蛋疼的办法还有传递Hash(有些人叫锚点),这是因为每次浏览器打开一个URL时,URL后面的#xxx部分会保留下来,那么新的页面可以从这里获得上一个页面的数据

五、跨域资源共享(CORS)

原理:服务器设置Access-Control-Allow-OriginHTTP响应头之后,浏览器将会允许跨域请求

限制:浏览器需要支持HTML5,可以支持POST,PUT等方法

前面提到的跨域手段都是某种意义上的Hack, HTML5标准中提出的跨域资源共享(Cross Origin Resource Share,CORS)才是正道。 它支持其他的HTTP方法如PUT, POST等,可以从本质上解决跨域问题。

例如,从http://a.com要访问http://b.com的数据,通常情况下Chrome会因跨域请求而报错

XMLHttpRequest cannot load http://b.com. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://a.com' is therefore not allowed access

错误原因是被请求资源没有设置Access-Control-Allow-Origin,所以我们在b.com的服务器中设置这个响应头字段即可

Access-Control-Allow-Origin: *              # 允许所有域名访问,或者
Access-Control-Allow-Origin: http://a.com   # 只允许所有域名访问

六、window.postMessage

原理:HTML5允许窗口之间发送消息

限制:浏览器需要支持HTML5,获取窗口句柄后才能相互通信

这是一个安全的跨域通信方法,postMessage(message,targetOrigin)也是HTML5引入的特性。 可以给任何一个window发送消息,不论是否同源。第二个参数可以是*但如果你设置了一个URL但不相符,那么该事件不会被分发。看一个普通的使用方式吧

// URL: http://a.com/foo
var win = window.open('http://b.com/bar');
win.postMessage('Hello, bar!', 'http://b.com');
// URL: http://b.com/bar
window.addEventListener('message',function(event) {
    console.log(event.data);
});

七、访问控制安全的讨论

在HTML5之前,JSONP已经成为跨域的事实标准了,jQuery都给出了支持。 值得注意的是它只是Hack,并没有产生额外的安全问题。 因为JSONP要成功获取数据,需要跨域资源所在服务器的配合,比如资源所在服务器需要自愿地回调一个合适的函数,所以服务器仍然有能力控制资源的跨域访问

跨域的正道还是要使用HTML5提供的CORS头字段以及window.postMessage, 可以支持POST, PUT等HTTP方法,从机制上解决跨域问题。 值得注意的是Access-Control-Allow-Origin头字段是资源所在服务器设置的, 访问控制的责任仍然是在提供资源的服务器一方,这和JSONP是一样的

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

更多精彩内容其他人还在看

32个典型的以分栏/网格为基础的网站

如果你正在寻找网页分栏设计的灵感,这里收集了32个典型的以分栏/网格为基础的网站。它们显示了在网页设计中分栏/网格的重要性,无论对于信息量巨大的站点还是个人博客。 1.The New York Times 2.National Post 3.Guardian 4.Times
收藏 0 赞 0 分享

理论普及——用户体验

一、概念分析1:UE用户体验 英文叫做user experience,缩写为UE, 或者UX。 当指电子商务网站的时候也被称作顾客体验(CUSTOMER EXPERIENCE). 它是指用户访问一个网站或者使用一个产品时的全部体验。他们的印象和感觉,是否成功,是否享
收藏 0 赞 0 分享

分页案例和好的实践

结构和层次降低了复杂性并提高了可读性。你的文章或站点组织的越深入,用户就越容易理解你观点和得到你想传达的信息。在网页上,这点被通过多个方式做到。 在正文头条和列举被用做逻辑上独立的数据块来呈现信息。另一种解决方法是一种叫分页的机制,它在给定文章的单一部
收藏 0 赞 0 分享

建立用户体验

也许你刚刚来到一家公司,他们希望进行一些“可用性”工作。你可能是一名UI设计师,业务分析师,或前端开发人员,一名产品经理,或者负责用户体验部门的经理或副总。你知道,如果更好地了解使用产品/软件/网站的人,就可能开发出更好的产品/软件/网站。不管怎么样
收藏 0 赞 0 分享

网页图片快速显示的方法和技巧

1. Use .gifs rather than .jpgs. GIFs are smaller in size when compared to JPGs. 1.用.gifs格式保存图片,最好不要用.jpgs格式。因为前者的尺寸比后者小。 2.Use 'Height
收藏 0 赞 0 分享

推荐60种分页案例和好的实践

结构和层次降低了复杂性并提高了可读性。你的文章或站点组织的越深入,用户就越容易理解你观点和得到你想传达的信息。在网页上,这点被通过多个方式做到。 在正文头条和列举被用做逻辑上独立的数据块来呈现信息。另一种解决方法是一种叫分页的机制,它在给定文章的单一部
收藏 0 赞 0 分享

全面的网站评估方案

有时会被问到“看看XXX网站如何?”之类的问题。 谈到评估,通常都是指产品级的网站,如果模式很新,了解需要花一定时间。于是,很多人又问“那么你仅从UI/UE的角度看看呢?”首先我们得达成共识,一切花里胡哨都在为功能服务,如果功
收藏 0 赞 0 分享

网页的栅格设计思考

原文地址:http://andymao.com/andy/post/82.html 网页设计中的脏、乱、差,是我们在设计过程中常会遇到的问题。通常"脏"是由对色彩使用不当所产生的,而色彩使用不当产生的不好效果也分为:"花、灰",花哨、
收藏 0 赞 0 分享

设计理论设计中的层次感

原文:http://andymao.com/andy/post/80.html 这段时间我一直在说设计需要有层次感,这种层次感可能有很多类型,比如色彩的层次感,或是元素的层次感。当一个设计缺乏层次感的时候页面所表现出来的无非是两种可能,一种是单调,一种是花哨。在设计中我们常
收藏 0 赞 0 分享

网页心得:网页色彩的搭配

网页的色彩是树立网站形象的关键之一,色彩搭配却是网友们感到头疼的问题。网页的背景,文字,图标,边框,超链接...,应该采用什么样的色彩,应该搭配什么色彩才能最好的表达出预想的内涵呢?这里谈一些心得,希望对你有所启发。 首先我们先来了解一些色彩的基本知识:
收藏 0 赞 0 分享
查看更多