XMLHttpRequest的跨域资源共享

由于浏览器的同源策略,非同源不可请求。但是,在实践当中,经常会出现需要跨域请求资源的情况,比较典型的例如某个子域名向负责进行用户验证的子域名请求用户信息等应用。

 

以前要实现跨域访问,可以通过JSONP、Flash或者服务器中转的方式来实现,但是现在我们有了CORS。

CORS与JSONP相比,无疑更为先进、方便和可靠。

1、 JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。

2、 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。

3、 JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS

 

 

Cross-Origin Resource sharing

这是W3C  新出的一个标准,简单的讲就是通过服务器/客户端 一些Headers的设置及确认 来实现跨域请求,这些包头有

  Cross-Origin Resource sharing

 

这是W3C  新出的一个标准,简单的讲就是通过服务器/客户端 一些Headers的设置及确认 来实现跨域请求,这些包头有

 Syntax

  1. 5.1 Access-Control-Allow-Origin Response Header
  2. 5.2 Access-Control-Allow-Credentials Response Header
  3. 5.3 Access-Control-Expose-Headers Response Header
  4. 5.4 Access-Control-Max-Age Response Header
  5. 5.5 Access-Control-Allow-Methods Response Header
  6. 5.6 Access-Control-Allow-Headers Response Header
  7. 5.7 Origin Request Header
  8. 5.8 Access-Control-Request-Method Request Header
  9. 5.9 Access-Control-Request-Headers Request Header

 

   例如

  • Access-Control-Allow-Origin: http://www.test.com
  • Access-Control-Allow-Methods: POST, GET, OPTIONS  
  • Access-Control-Allow-Headers: POWERED-BY-MENGXIANHUI  
  • Access-Control-Max-Age: 30

可以参考 http://www.w3.org/TR/access-control/#access-control-allow-origin-response-header  w3c的网站

 

Access-Control-Allow-Origin: 允许跨域访问的域,可以是一个域的列表,也可以是通配符"*"。这里要注意Origin规则只对域名有效,并不会对子目录有效。
即http://www.test/test/是无效的。但是不同子域名需要分开设置,这里的规则可以参照那篇同源策略
Access-Control-Allow-Credentials: 是否允许请求带有验证信息,这部分将会在下面详细解释
Access-Control-Expose-Headers: 允许脚本访问的返回头,请求成功后,脚本可以在XMLHttpRequest中访问这些头的信息(貌似webkit没有实现这个)
Access-Control-Max-Age: 缓存此次请求的秒数。在这个时间范围内,所有同类型的请求都将不再发送预检请求而是直接使用此次返回的头作为判断依据,非常有用,大幅优化请求次数
Access-Control-Allow-Methods: 允许使用的请求方法,以逗号隔开
Access-Control-Allow-Headers: 允许自定义的头部,以逗号隔开,大小写不敏感

 

Access-Control-Allow-Credentials

在跨域请求中,默认情况下,HTTP Authentication信息,Cookie头以及用户的SSL证书无论在预检请求中或是在实际请求都是不会被发送的。

但是,通过设置XMLHttpRequest的credentials为true,就会启用认证信息机制。

虽然简单请求还是不需要发送预检请求,但是此时判断请求是否成功需要额外判断Access-Control-Allow-Credentials,如果Access-Control-Allow-Credentials为false,请求失败。

十分需要注意的的一点就是此时Access-Control-Allow-Origin不能为通配符"*"(真是便宜了一帮偷懒的程序员),如果Access-Control-Allow-Origin是通配符"*"的话,仍将认为请求失败

即便是失败的请求,如果返回头中有Set-Cookie的头,浏览器还是会照常设置Cookie

 

客户端页面test.php

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">  
<head>  
<title>crossDomainRequest</title>  
</head>  
<body>  
<input type=‘button‘ value=‘开始测试‘ onclick="crossDomainRequest()"  />  
<div id="content"></div>  

<script type="text/javascript"> 
function createXHR(){
	return window.XMLHttpRequest?
	new XMLHttpRequest():
	new ActiveXObject("Microsoft.XMLHTTP");
}
function getappkey(url){
	xmlHttp = createXHR();
	xmlHttp.open("GET",url,false);
	xmlHttp.send();
	result = xmlHttp.responseText;
	return result;
}
function crossDomainRequest(){
	var content =getappkey(‘http://127.0.0.10/gettest.php‘);
	document.getElementById("content").innerHTML=content;
}
</script>  
</body>  
</html>  

 

服务端页面gettest.php

<?php
header("Access-Control-Allow-Origin:  http://127.0.0.1");
echo "test success!";
?>

 技术分享

 

 

如果不允许的话

技术分享

 

技术分享

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。