从原理分析CORS——咱们究竟是怎么跨域的

同源策略相信各位同窗已然不陌生了,在这里不作过多阐述,简单介绍一下就好:php

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 主域相同,子域不一样 不容许
http://www.a.com/a.js http://a.com/b.js 同一域名,不一样二级域名(同上) 不容许(cookie这种状况下也不容许访问)
http://www.cnblogs.com/a.js http://www.a.com/b.js 不一样域名 不容许

以上表格系统的阐述了如何算是跨域。json

那么下面咱们
今天咱们着重讲讲对抗同源策略的方法:
CORS——Cross-origin resource sharing(跨来源资源共享)跨域

因为HTML 5的概念造成,在原有XHR的基础上提出了XMLHttpRequest Level2(XHR2),在XHR2中对CORS有了很好的支持。(除了远古的IE8,IE9这些老古董)浏览器

咱们先看看看CORS平常是怎么实现跨域的服务器

• <?php  
•  /*
•  这里是简单的一个CORS Demo
•  */
• //经过请求体获取$_POST的name,gender
• $ret = array(  
•     'name' => isset($_POST['name'])? $_POST['name'] : '',  
•     'gender' => isset($_POST['gender'])? $_POST['gender'] : ''  
• );  
•   
• //HTTP_ORIGIN是请求头中的信息,在浏览器中直接展现为Origin
• $origin = isset($_SERVER['HTTP_ORIGIN'])? $_SERVER['HTTP_ORIGIN'] : '';  
• //此处是容许跨域的白名单
• $allow_origin = array(  
•     'http://www.client.com',  
•     'http://www.client2.com'  
• );  
• //判断当前Origin来源是否在白名单内,是的话就容许设置一套三式Header头让他跨域  
• if(in_array($origin, $allow_origin)){ 
•      //关键点是这里的一套三式 
•     header('Access-Control-Allow-Origin:'.$origin);  //容许的域名
•     header('Access-Control-Allow-Methods:POST');  //容许的方法
•     header('Access-Control-Allow-Headers:x-requested-with,content-type');  //服务器支持的头信息
• }  
•   
• echo json_encode($ret);  
• ?> 

关键词在header('Access-Control-Allow-*':) 一套三件,不一样若是没法经过这一套三件的洗礼,那么就报相似下面这样的错:cookie

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.

这个就是浏览器同源策略形成的,若是咱们没有设置Header头三件套的话('Access-Control-Allow-*':)那么对一切跨域请求操做浏览器都是拒绝的~。测试

可是随着互联网的发展,同源策略严重影响了项目之间的链接(尤为是大项目,有几个域名须要进行沟通的),W3C标准推出了“跨来源资源共享——CORS”。code

回到前面的那段实例代码,咱们来分析分析 请求-》处理-》返回 一套流程的前因后果。blog

CORS的背后基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求响应是应该成功仍是应该失败。
当Http请求发起(能够经过更新操做去测试POST,或者用JavaScript请求测试GET)的时候(不分跨不跨域)会相似带着如下请求头信息:ip

Origin:http://www.csdnblog.com

返回头也会夹带着相似以下信息:

Access-Control-Allow-Credentials:true 
Access-Control-Allow-Origin:http://www.csdnblog.com

一来一回的请求决定的请求决定了改请求是否会被浏览器经过,若是返回头中没有这个头部,或者有头部可是源信息不匹配(就是说返回头%-Allow-Origin中没有当前请求站点的域名),那么浏览器就会帮咱们驳回此次请求,同源策略在这里发挥了做用。

经过这一来一回咱们不难发现其实浏览器判断是否驳回的标准就是返回头中是否有 Access-Control-Allow-% 这个信息,而且判断这个信息是否合法(即这个信息是不是与请求头中的Origin对应的上),对应的上就经过,对应不上就驳回。

既然搞懂这个咱们就能够理解为什么经过CORS设置两三行Header代码既能够轻松跨域了吧?

服务端代码设置Header返回头告诉浏览器“谁谁谁是容许访问个人,你看到这家伙就给我放行吧~“。

因此若是在服务端代码中设置:

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

是的,这样的话任何域名均可以请求你的服务器了,固然这样子你的服务器也就很是危险了。

相关文章
相关标签/搜索