CORS(跨域资源共享) 笔记

0 简介

CORS(Cross-Origin Resource Sharing,跨域资源共享)是一种克服浏览器跨域HTTP请求限制的方法(PS:后端HTTP请求无跨域限制)。

采用CORS实现浏览器的跨域请求,有两个条件:一是浏览器支持CORS机制,目前大多数浏览器都是支持的;二是服务器有针对CORS机制的配置逻辑。

在浏览器端,是否通过CORS机制进行跨域请求,对于客户端编程来说是一样的,整个过程由浏览器执行,客户端代码无需额外的逻辑。

浏览器发现AJAX(XMLHttpRequest)请求的是跨域资源时,就会自动添加一下header(比如表示请求来源的Origin首部),如果是非简单请求则还会多出一次Options的请求。

1 区分简单请求与非简单请求

浏览器将跨域请求分为两类:简单请求(simple request)与非简单请求(not-so-simple request)。

满足以下条件,则为简单请求:

a. 请求方法是以下三种方法之一:

  • HEAD
  • GET
  • POST

b. header不超出以下几种字段:

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type,且只限于三个取值(application/x-www-form-urlencoded、multipart/form-data、text/plain)之一

不满足上述条件的,则为非简单请求。

2 浏览器发起请求

对于简单请求,浏览器在请求的header中自动带上Origin(包括协议、域名、端口),直接发起跨域请求即可。

对于非简单请求,浏览器会先执行一次预检(preflight)请求,询问服务器当前网页所在的域名,是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和首部。

预检请求的HTTP动词是Options,浏览器会在预检请求中带上此次非简单请求的相关信息,主要是3个首部:

  • Origin:此次非简单请求来源页面URL中的协议、域名、端口信息
  • Access-Control-Request-Method:此次非简单请求的HTTP动词
  • Access-Control-Request-Headers:由逗号分隔,为此次非简单请求中除简单请求中首部外,额外发送的首部的名称

浏览器只有得到预检请求的肯定答复后,才会发出正式的非简单请求(首部中会自动带上Origin);否则会报错。

3 服务端处理预检请求

首先是对预检请求的处理,服务器可以允许请求,也可以禁止请求。

如果允许此次请求,则返回200,并在响应中带上如下几个CORS相关的首部,且响应首部的值必须包含预检请求中的首部值

  • Access-Control-Allow-Origin:允许请求的源

  • Access-Control-Allow-Methods:允许的HTTP动词。最好一次性返回所有支持的方法,而不单是浏览器请求的那个方法,这样可以避免多次"预检"请求。

  • Access-Control-Allow-Headers:允许的首部。同理,返回所有允许的首部。

  • Access-Control-Allow-Credentials:是否允许带上认证信息,首部值为true。(若为false,则不需要在响应中带上该首部)

  • Access-Control-Max-Age:指定本次预检请求的有效期(单位为秒)。即允许缓存该条响应的时长,在此期间不用发出相同的预检请求。

如果拒绝该请求,仍旧返回200,但响应中没有上述的几个首部,或者有首部但不包含请求中的首部值

在服务端设置响应的CORS首部时,首部值可以预先配置好的值(一般用于正式环境),或是将响应首部值动态地设置成请求中的首部值(一般用于测试环境)。

比如对于 Access-Control-Allow-Origin 首部,在测试时直接设置成星号“*”,或是请求中的Origin的值。但在正式环境中,安全起见最好设置成特定的值。

如果在正式环境中,想在 Access-Control-Allow-Origin 首部中配置2个或多个值,不能直接用逗号分隔,而需要先把所有允许的Origin值存放在一个集合中,然后检查请求中的Origin是否包含在该集合中,若是则将 Access-Control-Allow-Origin 设置成对应Origin值,否则不添加 Access-Control-Allow-Origin 首部。

4 服务端处理正式的请求 

同样,对于正式的数据请求,服务端也可以允许或拒绝。

允许请求的话,则在响应中带上跟预检请求响应中相同的CORS首部,且首部值包含请求中相关的首部值

拒绝请求时,则响应中不带上相关的CORS首部,或是首部值不包含请求中的首部值。

5 浏览器处理响应

参考文献

猜你喜欢

转载自www.cnblogs.com/haycheng/p/12974376.html
今日推荐