CORS,即跨源资源共享(Cross-Origin Resource Sharing),是一种允许在一个源(origin)上的网页获取访问另一个源上资源的机制。它是一种安全特性,可以让网站的前端代码安全地进行跨域请求,而不会暴露用户数据。
CORS 请求分为两类:简单请求(simple requests)和复杂请求(preflighted requests)。它们之间的区别主要体现在请求的方式和所发送内容上。
简单请求
简单请求满足以下条件:
- 请求方法是以下三种方法之一:
- GET
- POST
- HEAD
- HTTP的头信息不超出以下几种字段:
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type(只限于三个值
application/x-www-form-urlencoded
、multipart/form-data
、text/plain
)
简单请求的例子:
httpGET /some/resource HTTP/1.1 Host: api.example.com Accept-Language: en-US Content-Type: text/plain
当浏览器判断一个请求为简单请求时,它会直接发起跨域请求,并在请求中携带Origin
头部信息。服务端会检查这个Origin
,决定是否允许这个跨域请求。
复杂请求
复杂请求通常指不满足以上简单请求条件的所有其他请求,例如:
- 使用了 PUT、DELETE、CONNECT、OPTIONS、TRACE、PATCH 等 HTTP 方法。
- 发送的 HTTP 头部信息超出了简单请求允许的范围。
- Content-Type 的值不属于简单请求中允许的三个值。
在发送复杂请求之前,浏览器会先发起一个 OPTIONS 请求,这被称为“预检”请求(preflight request),用来确认真正的请求是否安全可被服务器接受。预检请求的例子:
httpOPTIONS /data/resource HTTP/1.1 Host: api.example.com Origin: http://example.com Access-Control-Request-Method: POST Access-Control-Request-Headers: X-Custom-Header
如果服务器允许这样的请求,它会在响应的 HTTP 头部中包含Access-Control-Allow-Origin
、Access-Control-Allow-Methods
和Access-Control-Allow-Headers
等字段,明确告知客户端是否可以进行实际的请求。之后,浏览器才会发送实际的请求。
总结
简单来说,简单请求是对CORS更宽容的请求,直接发起并通过Origin
头部判断是否允许跨域;而复杂请求需要先进行一次额外的预检通信以确认安全性,只有在预检通过后,实际的请求才会发起。这个机制确保了敏感操作(如对数据的修改)在跨域时能够得到恰当的安全检查。