在本地用ajax跨域访问请求时报错:


XMLHttpRequest cannot loadhttp://www.zjblogs.com/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.


查了一翻资料,发现原来是新W3C标准中是这样规定的:


最新的W3C标准里是这么实现HTTP跨域请求的, Cross-Origin Resource Sharing


简单的来说,就是跨域的目标服务器要返回一系列的Headers,通过这些Headers来控制是否同意跨域。这些Headers有:4 Syntax


4.1 Access-Control-Allow-Origin HTTP Response Header

4.2 Access-Control-Max-Age HTTP Response Header

4.3 Access-Control-Allow-Credentials HTTP Response Header

4.4 Access-Control-Allow-Methods HTTP Response Header

4.5 Access-Control-Allow-Headers HTTP Response Header

4.6 Origin HTTP Request Header

4.7 Access-Control-Request-Method HTTP Request Header

4.8 Access-Control-Request-Headers HTTP Request Header


在 Request 包和 Response 包中都有一些。

其中最敏感的就是 Access-Control-Allow-Origin 这个 Header, 他是W3C标准里用来检查该跨域请求是否可以被通过。 (Access Control Check)


跨域实现的过程大致如下:


从 http://www.a.com/test.html 发起一个跨域请求,


请求的地址为: http://www.b.com/test.PHP


如果 服务器B返回一个如下的header


Access-Control-Allow-Origin: http://www.a.com


那么,这个来自 http://www.a.com/test.html 的跨域请求就会被通过。



如上所知,总结解决办法如下:


1、如果请求的url是aspx页面,则需要在aspx页面中添加代码:Response.AddHeader("Access-Control-Allow-Origin", "*");


2、如果请求的url是PHP页面,则需要在PHP页面中添加代码:header("Access-Control-Allow-Origin: *");


3、如果请求的url是静态的html页面,则需要在页面中添加meta标签代码:<meta http-equiv="Access-Control-Allow-Origin" content="*" />


如果服务器端可以确定是要被哪些域名访问,最好是能把以上代码中的“*”代替为具体的域名,这样做可以相应的安全性。



如果还不行,就把这些都加上吧

// 指定允许其他域名访问    

header('Access-Control-Allow-Origin:*');    

// 响应类型    

header('Access-Control-Allow-Methods:POST');    

// 响应头设置    

header('Access-Control-Allow-Headers:x-requested-with,content-type');  




 传统的跨域请求没有好的解决方案,无非就是jsonp和iframe,随着跨域请求的应用越来越多,W3C提供了跨域请求的标准方案(Cross-Origin Resource Sharing)。IE8、Firefox 3.5 及其以后的版本、Chrome浏览器、Safari 4 等已经实现了 Cross-Origin Resource Sharing 规范,实现了跨域请求。
在服务器响应客户端的时候,带上Access-Control-Allow-Origin头信息

  • 如果设置 Access-Control-Allow-Origin:*,则允许所有域名的脚本访问该资源。

  • Access-Control-Allow-Origin:http://www.phpddt.com.com,允许特定的域名访问。


 如PHP添加响应头信息:


  1. header("Access-Control-Allow-Origin: *");



Cross-Origin Resource Sharing协议介绍


传统的Ajax请求只能获取在同一个域名下面的资源,但是HTML5打破了这个限制,允许Ajax发起跨域的请求。浏览器是可以发起跨域请求的,比如你可以外链一个外域的图片或者脚本。但是Javascript脚本是不能获取这些资源的内容的,它只能被浏览器执行或渲染。

在Flash和Silverlight中,服务器需要创建一个crossdomain.xml的文件来允许跨域请求。如果这个文件声明“http://your.site”允许来自“http://my.site”的请求,则来自“http://my.site”的请求可以访问所有“http://your.site”的文件。这是一种整个站点层面上的控制模式,要么你允许一个外域的站点访问,要么拒绝。

COR不一样,它是页面层次的控制模式。每一个页面需要返回一个名为‘Access-Control-Allow-Origin’的HTTP头来允许外域的站点访问。你可以仅仅暴露有限的资源和有限的外域站点访问。在COR模式中,访问控制的职责可以放到页面开发者的手中,而不是服务器管理员。当然页面开发者需要写专门的处理代码来允许被外域访问。

另外一个主要的区别是,某个站点的crossdomain.xml文件是最早被浏览器获取并分析的。如果一个外域的站点不允许被访问,浏览器压根就不会发出跨域请求。

COR则相反,Javascript先发出跨域请求,然后检查回复的‘Access-Control-Allow-Origin’头。如果这个头允许该外域访问,则Javascript可以读取这个回复,否则就被禁止访问。如果请求不是一个简单的COR,则向外域服务器发送预检验请求,如果回复的头部允许访问,则发送跨域请求,否则禁止。

COR的实现标准就是CORS协议。

对于浏览器来说,COR请求都是Javascript发起的,COR请求有两种:

1、简单的COR请求,它可以直接向外域资源发起请求。它必须仅仅包含简单的方法和头,具体定义看[2] 6.1。

2、如果COR包含复杂的方法和头,它需要发出预检验(Preflight)请求,它先向资源服务器发出一个OPTIONS方法、包含“Origin”头的请求。该回复可以控制COR请求的方法,HTTP头以及验证等信息。只有该请求获得允许以后,才会发起真实的外域请求。

下面是一个简单的COR请求:

<script language="Javascript" type="text/javascript">

var client = new XMLHttpRequest();

client.open("GET", "http://bar.org/b")

client.onreadystatechange = function() { /* do something */ }

client.send()

</script>

假设这个请求所在页面的域是“http://foo.org”。 如果来自“http://bar.org/b”的回复包含这样的头:

Access-Control-Allow-Origin: http://foo.org

则表明,它允许来自“http://foo.org”的跨域请求。

下面的Javascript会发出预检验请求和真实请求:

<script language="Javascript" type="text/javascript">

var client = new XMLHttpRequest();

client.open("GET", "http://bar.org/b")

client.setRequestHeader('Content-Type','text/html')

client.onreadystatechange = function() { /* do something */ }

client.send()

</script>

由于“Content-type: text/html”不是一个简单的头,它会先向"http://bar.org/b"发出一个OPTIONS的HTTP请求。 回复可能包含这样的头:

Access-Control-Allow-Origin: http://foo.org

Access-Control-Max-Age: 3628800

Access-Control-Allow-Methods: GET,PUT, DELETE

Access-Control-Allow-Headers: content-type

"Access-Control-Allow-Origin"表明它允许"http://foo.org"发起跨域请求

"Access-Control-Max-Age"表明在3628800秒内,不需要再发送预检验请求,可以缓存该结果

"Access-Control-Allow-Methods"表明它允许GET、PUT、DELETE的外域请求

"Access-Control-Allow-Headers"表明它允许跨域请求包含content-type头

如果预检验请求获得通过,接下来Javascript就会发起真实的COR请求,过程跟简单的COR请求类似。

CORS协议的实现

现在HTML5的标准如火如荼的在制定和发展中,CORS作为HTML5的一部分,在大部分现代浏览器中有所支持,支持(部分支持)CORS协议的浏览器有IE8+, Firefox5+, Chrome12+, Safari4+


© 著作权归作者所有,未经允许《“No 'Access-Control-Allow-Origin' header is present on the requested resource.”错》不得转载

相关文章

最新文章

热门文章

热门TAG