We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
近期在工作中用到了cors,所以写下这篇分享,本文基于koa-cors 1.0.1。
koa-cors 1.0.1
Cross-Origin Resource Sharing(cors),顾名思义,跨域资源共享,也就是一种实现跨域的手段,想要的解决的问题是跟使用jsonp一样的。要想知道跨域是为了什么,得先知道什么是跨域。跨域(cross-orgin)是因为有同源策略(same-origin policy)的存在。浏览器为了保证加载的脚本等资源都是可控安全的,就加了一个强制性的规定,非同域名下的资源不得加载。同域名是指两个域名之间,端口,协议,以及子域都应相同
这是与http://www.alipay.com的通信结果
在chrome的network面板里可以看到,发给非同域的请求其实是发出去了的,只是浏览器在拿到对方服务器返回的时候数据时,看到这个响应并不是从当前域名返回的,就302了这个响应,同时报了个错。这样看来,跨域都是浏览器的锅,jsonp、iframe等手段都是为了绕过这一障碍才发明的。浏览器也不愿天天背这个锅,码农何苦为难码农,于是出现了cors这一手段,让浏览器天生支持跨域。
cors的实现非常简单,前端甚至都不需要做修改,只需要在对方服务端的响应头里加个字段Access-Control-Allow-Origin就可以了。Access-Control-Allow-Origin的值可以是*,也就是代表任何域名都可以来拿我的资源,也可以指定域名,只有指定的域名可以拉取资源。
Access-Control-Allow-Origin
cors还有些特性也需要详说的:
预校验是指某些特殊情况下,需要在发送真正的ajax请求之前发送一个options方法的请求,来『探测』一下我们的请求服务端接不接受,当然这一步是浏览器自动的,无需手动。『特殊情况』就是指下面的两种情况:
options
get
head
post
Content-Type
application/x-www-form-urlencoded
multipart/form-data
text/plain
application/xml
在预请求的请求头里会额外再带上两个字段,分别是Access-Control-Request-Method(必带),Access-Control-Request-Headers(如果设置了自定义请求头),Access-Control-Request-Method的值就是该ajax请求所用的方法。
Access-Control-Request-Method
Access-Control-Request-Headers
可能有的同学会说,这根本不给力啊,如果我们做的是安全性比较高的服务,cors过来的请求根本没法做校验,很可能会出安全事故啊~ w3c的同学都不是吃素的,早就为你考虑到啦!一般来说,跨域的ajax请求是不带cookie的,而cors的ajax请求就不一样了,人家可以带cookie去服务端,这样就可以让服务端来判断这个请求是否合法。而且让ajax带cookie很简单,一句话的事儿:xhr.withCredentials = true;。若服务端认为这个请求是合法的,返回的响应头里必须带上Access-Control-Allow-Credentials: true,若为其他值或不带这个字段,浏览器会把withCredentials发出的请求的响应通通拒绝掉。
xhr.withCredentials = true;
Access-Control-Allow-Credentials: true
withCredentials
这项技术的浏览器兼容情况还是不错的,IE8 ~ IE9使用XDomainRequest,其他浏览器都使用XMLHttpRequest原生支持。
XDomainRequest
说完了cors和cors的原理,我们接着来讲koa-cors。
var koa = require('koa'); var cors = require('kcors'); var app = koa(); app.use(cors());
cors方法可以传入一个对象options
{ origin:允许发来请求的域名,对应响应的`Access-Control-Allow-Origin`, allowMethods:允许的方法,默认'GET,HEAD,PUT,POST,DELETE',对应`Access-Control-Allow-Methods`, exposeHeaders: 允许客户端从响应头里读取的字段,对应`Access-Control-Expose-Headers`, allowHeaders:这个字段只会在预请求的时候才会返回给客户端,标示了哪些请求头是可以带过来的,对应`Access-Control-Allow-Headers`, maxAge:也是在预请求的时候才会返回,标明了这个预请求的响应所返回信息的最长有效期,对应`Access-Control-Max-Age` credentials:标示该响应是合法的,对应`Access-Control-Allow-Credentials` }
var requestOrigin = this.get('Origin'); if (!requestOrigin) { return yield* next; }
如请求头不带Origin字段,说明根本不是cors请求,直接忽略。
if (this.method !== 'OPTIONS') { ... } else { ... if (!this.get('Access-Control-Request-Method')) { // this not preflight request, ignore it return yield* next; } ... }
若该请求不是OPTIONS方法,说明不是预请求,则根据options中的字段设置响应头,若该方法是OPTIONS方法,但不带Access-Control-Request-Method,说明不是预请求,仍然直接忽略。
OPTIONS
this.status = 204;
在设置完需要设置的字段后,由于不需要返回具体内容,到这里就可以直接返回个204了。204表示不带响应体的成功响应。
The text was updated successfully, but these errors were encountered:
什么是跨域的描述太表面,可以继续深挖。
对于代码的解读,应该直接贴代码,只说第几行根本不知道在说啥。代码一旦变动,行号就对应不上了
Sorry, something went wrong.
ok 已更新
No branches or pull requests
近期在工作中用到了cors,所以写下这篇分享,本文基于
koa-cors 1.0.1
。啥是cors呢
Cross-Origin Resource Sharing(cors),顾名思义,跨域资源共享,也就是一种实现跨域的手段,想要的解决的问题是跟使用jsonp一样的。要想知道跨域是为了什么,得先知道什么是跨域。跨域(cross-orgin)是因为有同源策略(same-origin policy)的存在。浏览器为了保证加载的脚本等资源都是可控安全的,就加了一个强制性的规定,非同域名下的资源不得加载。同域名是指两个域名之间,端口,协议,以及子域都应相同
这是与http://www.alipay.com的通信结果
在chrome的network面板里可以看到,发给非同域的请求其实是发出去了的,只是浏览器在拿到对方服务器返回的时候数据时,看到这个响应并不是从当前域名返回的,就302了这个响应,同时报了个错。这样看来,跨域都是浏览器的锅,jsonp、iframe等手段都是为了绕过这一障碍才发明的。浏览器也不愿天天背这个锅,码农何苦为难码农,于是出现了cors这一手段,让浏览器天生支持跨域。
cors的实现非常简单,前端甚至都不需要做修改,只需要在对方服务端的响应头里加个字段
Access-Control-Allow-Origin
就可以了。Access-Control-Allow-Origin
的值可以是*,也就是代表任何域名都可以来拿我的资源,也可以指定域名,只有指定的域名可以拉取资源。cors还有些特性也需要详说的:
预请求(Preflighted)
预校验是指某些特殊情况下,需要在发送真正的ajax请求之前发送一个
options
方法的请求,来『探测』一下我们的请求服务端接不接受,当然这一步是浏览器自动的,无需手动。『特殊情况』就是指下面的两种情况:get
、head
和post
之外的方法,或post请求的Content-Type
是application/x-www-form-urlencoded
、multipart/form-data
、text/plain
以外的,如application/xml
等时;在预请求的请求头里会额外再带上两个字段,分别是
Access-Control-Request-Method
(必带),Access-Control-Request-Headers
(如果设置了自定义请求头),Access-Control-Request-Method
的值就是该ajax请求所用的方法。带上cookie的ajax跨域请求(credentials)
可能有的同学会说,这根本不给力啊,如果我们做的是安全性比较高的服务,cors过来的请求根本没法做校验,很可能会出安全事故啊~ w3c的同学都不是吃素的,早就为你考虑到啦!一般来说,跨域的ajax请求是不带cookie的,而cors的ajax请求就不一样了,人家可以带cookie去服务端,这样就可以让服务端来判断这个请求是否合法。而且让ajax带cookie很简单,一句话的事儿:
xhr.withCredentials = true;
。若服务端认为这个请求是合法的,返回的响应头里必须带上Access-Control-Allow-Credentials: true
,若为其他值或不带这个字段,浏览器会把withCredentials
发出的请求的响应通通拒绝掉。这项技术的浏览器兼容情况还是不错的,IE8 ~ IE9使用
XDomainRequest
,其他浏览器都使用XMLHttpRequest原生支持。koa-cors
说完了cors和cors的原理,我们接着来讲koa-cors。
使用
cors方法可以传入一个对象options
如请求头不带Origin字段,说明根本不是cors请求,直接忽略。
若该请求不是
OPTIONS
方法,说明不是预请求,则根据options中的字段设置响应头,若该方法是OPTIONS
方法,但不带Access-Control-Request-Method
,说明不是预请求,仍然直接忽略。在设置完需要设置的字段后,由于不需要返回具体内容,到这里就可以直接返回个204了。204表示不带响应体的成功响应。
The text was updated successfully, but these errors were encountered: