什么是CORS

CORS(Cross-OriginResource Sharing)是由 W3C 制定的一种跨域资源共享技术标准,其目的就是为了解决前端的跨域请求。在 JavaEE 开发中,最常见的前端跨域请求解决方案是 JSONP,但是 JSONP 只支持 GET 请求,这是一个很大的缺陷,而 CORS 则支持多种 HTTP 请求方法,也是自前主流的跨域解决方案。

CORS 中新增一组 HTTP 请求头字段,通过这些字段,服务器告诉浏览器,哪些网站通过浏览器有权限访问哪些资源。同时规定,对那些可能修改服务器数据的 HTTP 请求方送(如 GET 以外的 HTTP 请求等),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),预检请求的目的是查看服务端是否支持即将发起的跨域请求,如果服务端允许,才能发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(如 Cookies、HTTP 认证信息等)。

以 GET 请求为例,如果需要发起一个跨域请求,则请求头如下:

Host: localhost:8080
origin: http://localhost:8081
Referer: http://localhost:8081/index.html
....

如果服务端支持该跨域请求,那么返回的响应头中将包含如下字段:

Access-Control-Allow-origin: http://localhost:8081

Access-Control-Allow-Origin 字段用来告诉浏览器可以访问该资源的域,当浏览器收到这样的响应头信息之后,提取出 Access-Control-Allow-Origin 字段中的值,发现该值包含当前页面所在的域,就知道这个跨域是被允许的,因此就不再对前端的跨域请求进行限制。

这属于简单请求,即不需要进行预检请求的跨域。

对于一些非简单请求,会首先发送一个预检请求。预检请求类似下面这样:

OPTIONS /put HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Accept:*/*
Access-Control-Reguest-Method: PUT
origin: http://localhost:8081
Referer: http://localhost:8081/index.html
.....

请求方法是 OPTIONS,请求头 Origin 字段告诉服务端当前页面所在的域,请求头 Access-Control-Request-Method 告诉服务端即将发起的跨域请求所使用的方法。服务端对此进行判断,如果充许即将发起的跨域请求,则会给出如下响应:

HTTP/1.1 200
Access-control-Allow-Origin: http://localhost:8081
Access-Control-Allow-Methods: PUT
Access-control-Max-Age: 3600
.....

Access-Control-Allow-Methods 字段表示允许的跨域方法;Access-Control-Max-Age 字段表示预检请求的有效期,单位为秒,在有效期内如果发起该跨域请求,则不用再次发起预检请求。预检请求结束后,接下来就会发起一个真正的跨域请求,跨域请求和前面的 GET 请求步骤类似,此处不再赘述。

这是我们关于 CORS 的一个简单介绍。