这是一个W3C标准(显然比jsonp背景深厚许多),同样需要浏览器和服务器同时支持,但是整个通信过程,都是浏览器自动完成,不需要用户参与,就像平时写Ajax一样(如果使用的是jquery的话)。下面是原生js实现CORS的代码
function createCORSRequest(method,url){ var xhr=new XMLHttpRequest(); if("withCredentials" in xhr){ xhr.open(method,url,true); }else if(typeof XDomainRequest != "undefined"){//IE10之前的版本使用XDmainRequest支持CORS xhr=new XDomainRequest(); xhr.open(method,url); }else{ xhr=null; } return xhr; } var request=createCORSRequest("get","待访问的地址"); if(request){ request.onload=function(data){ //do sth }; request.send(); }承载的信息量大,get形式搞不定,需选用post传输。CORS支持所有类型的传输。
移动端全面支持(除opera mini),PC上IE8+。
使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。(请求和响应都不包含cookie)
当然如果设置成下面这样,所有的跨域都可以实现了,但这样毕竟太不安全。“Access-Control-Allow-Origin:*”;//允许任何域向我们的服务器发送请求
一般情况下,浏览器发送一个额外的Origin头部(由浏览器自动生成发送) Origin:http://localhost:8080//本地网址然后由服务器发送一个响应表头:Access-Control-Allow-Origin,如果服务器接收该请求,返回值(只能是通配符或单域名。)就和请求值一样。
Access-Control-Allow-Origin:http://localhost:8080=>CORS方案的重点其实就在于服务器端的配置。
对于简单请求,浏览器直接发出CORS请求。浏览器会自动在头信息(Request Headers)中,添加一个Origin 字段,来表明本次请求来自哪个域。
Paste_Image.png如果这个源不在许可范围内,会报错: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
如果Origin指定的域名在许可范围内(必须是跨域了的),Response Headers中会多出几个头信息字段。
Access-Control-Allow-Credentials:true//值为true表示允许发送cookie Access-Control-Allow-Methods:GET, POST, OPTIONS Access-Control-Allow-Origin:http://localhost:8080 Access-Control-Max-Age:1728000因为CORS默认不发送cookie和http认证,如果要把Cookie发到服务器,就要指定Access-Control-Allow-Credentials:true;另外AJAX中也要打开withCredentials属性。
var xhr=new XMLHttpRequest(); xhr.withCredentials=true;jquery ajax请求参数中加入
xhrFields: { withCredentials: true }除了上面说的简单请求外都是非简单请求,比如:请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json,又或者有自定义请求头Access-Control-Request-Headers: X-Custom-Header。
比如,我添加自定义请求头
xhr.setRequestHeader('Some-Custom-Response-Header', 'value');就会发现连续向同一地址请求了两次,而第一次请求什么值也没拿到
Paste_Image.png第二次请求
Paste_Image.png这是因为浏览器发现,这是一个非简单请求,就自动发出一个”预检”请求,要求服务器确认可以这样请求。”预检”请求用的请求方法是OPTIONS,表示这个请求是用来询问的。”预检”请求之后,浏览器球会进行正常CORS请求。
1、可以参考这个方法:为 RESTful API 配置 CORS 实现跨域请求,写的挺详细的。然而对于rails并不算熟悉的我来说,有gem包,怎么可能放着不用呢~2、这是Rack CORS 中间件的项目地址,按照文档的说明1分钟就可以基本搞
