CROS
通常在浏览器中会遇到如下的报错。
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at http://example.com/api/login.
(Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
这源于浏览器中的同源策略,主要是为了防止出现跨站请求伪造攻击。
通常,会通过 cookie
保存认证和维持 Session 信息,例如当登录 facebook.com
之后会保存相应的 cookie
信息,这样后续就无需重新登录。
当打开了 evil.com
异常网站之后,如果在该网站中访问了 facebook.com
的接口,同时又因为之前登录的 cookie
信息,那么就可以伪造发送相关请求。
但是,可能同时会拦截掉一些正常请求,如下分成两种类型进行处理。
简单请求
发送的请求头中同时会包含 Origin
字段,例如如下的示例。
GET /api/login HTTP/1.1
Origin: http://api.foobar.com
通过 Origin
标识请求来源,包括了协议、域名、端口,服务器根据改信息决定是否同意这次请求。
如果 Origin
指定的源在服务器允许范围内,那么服务器会返回包含 Access-Control
相关的头,如果不包含那么就会抛出异常,相关的头包含如下几个:
Access-Control-Allow-Origin
必须,要么是请求时的Origin
字段值,要么是*
表示允许任意域名请求。Access-Control-Allow-Credentials
可选,是否允许发送 Cookie,只能设置为true
,如果不允许那么直接删除即可。Access-Control-Expose-Headers
可选。
非简单请求
常见的是 PUT
DELETE
或者 Content-Type
字段为 application/json
类型,此种类型会正式发送请求前增加一次预检请求,也就是 OPTIONS
类型,关键字段同样为 Origin
头,同时还包含如下几个字段:
Access-Control-Request-Method
必须,用来列出浏览器请求会用到的方法。Access-Control-Request-Headers
可选,通过逗号分割,标识 CORS 请求会额外发送的头信息字段。
服务器返回头,除了上述 Access-Control-Allow-Origin
和 Access-Control-Allow-Credentials
之外,还支持如下:
Access-Control-Allow-Methods
允许的操作方法,例如GET, POST, PUT
。Access-Control-Allow-Headers
允许的头信息。Access-Control-Max-Age
可选,用来指定本次预检请求的有效期,单位为秒。