文档介绍:Spring MVC配置CORS(解决跨域请求)
1. CORS 简介
同源策略(same origin policy)是浏览器安全的基石。在同源策略的限制下,非同源的网站之间不能发送 ajax 请求的。
为了解决这个问题,w3c 提出了跨源资源共享,即 CORS(Cross-Origin Resource Sharing)。
CORS 做到了两点:
不破坏即有规则服务器实现了 CORS 接口,就可以跨源通信
基于这两点,CORS 将请求分为两类:简单请求和非简单请求。
简单请求
可以先看下 CORS 出现前的情况:跨源时能够通过 script 或者 image 标签触发 GET 请求或通过表单发送一条 POST 请求,但这两种请求 HTTP 头信息中都不能包含任何自定义字段。
简单请求对应该规则,因此对简单请求的定义为:
请求方法是 HEAD、GET 或 POST 且 HTTP 头信息不超过以下几个字段:Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type(只限于 application/x-www-form-urlencoded、multipart/form-data、text/plain)。
比如有一个简单请求:
GET /test HTTP/
Accept: */*
Accept-Encoding: gzip, deflate, sdch, br
Origin:
Host:
对于这样的简单请求,CORS 的策略是请求时,**在头信息中添加一个 Origin 字段**,服务器收到请求后,根据该字段判断是否允许该请求。
如果允许,则在 HTTP 头信息中添加 Access-Control-Allow-Origin 字段,并返回正确的结果如果不允许,则不在头信息中添加 Access-Control-Allow-Origin 字段。
浏览器先于用户得到返回结果,根据有无 Access-Control-Allow-Origin 字段来决定是否拦截该返回结果。
对于 CORS 出现前的一些服务,CORS 对他们的影响分两种情况:
script 或者 image 触发的 GET 请求不包含 Origin 头,所以不受到 CORS 的限制,依旧可用。如果是 ajax 请求,HTTP 头信息中会包含 Origin 字段,由于服务器没有做任何配置,所以返回结果不会包含 Access-Control-Allow-Origin,因此返回结果会被浏览器拦截,接口依旧不可以被 ajax 跨源访问。
可以看出,CORS 的出现,没有对”旧的“服务造成任何影响。
另外,除了提到的 Access-Control-Allow-Origin 还有几个字段用于描述 CORS 返回结果:
Access-Control-Allow-Credentials: 可选,用户是否可以发送、处理 cookie。Access-Control-Expose-Headers:可选,可以让用户拿到的字段。有几个字段无论设置与否都可以拿到的,包括:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。
非简单请求
除了简单请求之外的请求,就是非简单请求。
对于非简单请求的跨源请求,**浏览器会在真实请求发出前**,增加一次 OPTION 请求,称为预检请求(preflight request)。预检请求将真实请求的信息,包括请求方法、自定义头字段、源信息添加到 HTTP 头信息字段中,询问服务器是否允许这样的操作。
比如对于 DELETE 请求:
OPTIONS /test HTTP/
Origin:
Access-Control-Request-Method: DELETE
Access-Control-Request-Headers: X-Custom-Header
Host:
与 CORS 相关的字段有:
Access-Control-Request-Method: 真实请求使用的 HTTP 方法。Access-Control-Request-Headers: 真实请求中包含的自定义头字段。
服务器收到请求时,需要分别对 Origin、Access-Control-Request-Method、A