CORS(Cross-Origin Resource Sharing) 跨域资源共享javascript
CORSphp
全称:Cross-Origin Resource Sharinghtml
中文意思:跨域资源共享?前端
好吧,目前中文方面的资料还比较少,能搜索到的那仅有的几篇相关介绍,也几乎是雷同的。html5
最近工做上也有用到CORS的地方,随便作点分享吧,也当是笔记。java
你们也知道,XMLHttpRequest接口是Ajax的根本,而Ajax考虑到安全性的问题,是禁止跨域访问资源的。ajax
也就是说:www.a.com的页面没法经过Ajax来调用www.b.com的资源。json
不少人又会说,但jQuery的$.ajax()明明就能够跨域访问啊!跨域
对,的确是跨了,但那是jsonp!关于jsonp的介绍也不少了,这里不扯。浏览器
其实jQuery的$.ajax()方法中,也能够实现CORS,只要服务器端配合,跨域就不须要使用jsonp。
CORS是XMLHttpRequest Level 2中新增长的功能
支持状况以下
支持状况还算良好(假如无视IE的话)。
移动端的开发,除了Opera Mini还不支持,其余设备的版本支持状况也很好。
好了,下面进入实战,直接说说使用方法。
1 var xhr = new XMLHttpRequest(); 2 xhr.open("POST", "http:// www.2cto.com ", true); 3 xhr.send();没有看错!就是这么简单!
和Ajax的调用方法是毫无差别的,须要的只是服务器端的配合。
服务器端如何配置?
PHP:只须要使用以下的代码设置便可。
1 <?php 2 header("Access-Control-Allow-Origin:*"); 以上的配置的含义是容许任何域发起的请求均可以获取当前服务器的数据。
固然,这样有很大的危险性,恶意站点可能经过XSS攻击咱们的服务器。
若是仅支持www.a.com这个站跨域访问,那就:
1 <?php 2 header("Access-Control-Allow-Origin: http://www.a.com"); 这样就基本配置ok了~
前端的部分,若是须要跨域向服务器发cookies
还须要设置一个属性:withCredentials
1 var xhr = new XMLHttpRequest(); 2 xhr.open("POST", "http://www.b.com", true); 3 xhr.withCredentials = true; //支持跨域发送cookies 4 xhr.send(); 固然,服务器端也要设置
1 <?php 2 header("Access-Control-Allow-Credentials: true");
好吧,下面说说须要注意的地方。
若是不使用第三方库,用原生javascript来写,仍是有些地方须要注意的。
一、不要设置X-Requested-With头
由于跨域访问,如需带header,服务器端必需要allow,否则报错。
setRequestHeader("X-Requested-With", "XMLHttpRequest")主要用在Ajax调用资源时,服务器能判断该次请求是Ajax的。
二、INVALID_STATE_ERR: DOM Exception 11
这是一个神奇的错误,网上找了一下,也没什么较为明确的答复。但我却在手机端遇到了这个问题!
测试了一下:在IOS4和IOS5的UC浏览器、Safari、Chrome,进行CORS访问均会报这个错,
Android4.0原生浏览器,也没法正常CORS(没有测试2.3和2.2)
估计也是报这个错,但没控制台,因此没法查bug。
Android4.0下的Chrome和UC均可以顺利CORS。
本觉得是浏览器兼容的问题,通过蛋疼的排查以后,发现...
咱们能够看一下,下面两段代码有啥差别?
1 var xhr = new XMLHttpRequest(); 2 xhr.withCredentials = true; //支持跨域发送cookies 3 xhr.open("POST", "http://weibo.com/demo/b/index.php", true); 4 xhr.send();1 var xhr = new XMLHttpRequest(); 2 xhr.open("POST", "http://weibo.com/demo/b/index.php", true); 3 xhr.withCredentials = true; //支持跨域发送cookies 4 xhr.send();惟一的差别就是xhr.withCredentials = true; 的位置。
但就是这个差异,致使第一段代码没法顺利在手机端运行,并报INVALID_STATE_ERR: DOM Exception 11这个错!
而在桌面版浏览器下,两段代码均可以顺利运行!
因此,之后设置withCredentials属性时,必定要在open方法以后!
篇幅有限,想要参考更多的CORS,能够查看下面的参考网站.
参考:
http://www.html5rocks.com/en/tutorials/cors/
https://developer.mozilla.org/en-US/docs/HTTP_access_control (MDN十分详细的讲解)
http://enable-cors.org/index.html (不一样的服务器怎么配置CORS)
http://people.opera.com/tiffanyb/2011/cors/ (来自Opera的CORS测试Demo)
http://arunranga.com/examples/access-control/ (另外一个CORS的测试Demo)