说说CORS为何要区分预检请求和简单请求呢?
CORS(跨域资源共享)区分预检请求(preflight request)和简单请求是为了在保证安全性的前提下,尽可能地减少跨域请求的 overhead。简单请求可以直接发送,而预检请求则需要先发送一个 OPTIONS 请求进行确认,这增加了额外的请求次数。
区分的原因在于某些跨域请求可能会对服务器数据造成修改,存在安全风险。为了防止恶意攻击,浏览器需要对这些“非简单”请求进行更严格的控制。
具体来说:
-
简单请求: 不会对服务器数据造成副作用的请求,浏览器可以直接发送。服务器通过响应头来表明是否允许该跨域请求。 对于简单请求,浏览器会在实际请求中添加
Origin
头,服务器根据这个头来判断是否允许跨域。 -
预检请求 (OPTIONS 请求): 对于一些“非简单”请求,浏览器会先发送一个 OPTIONS 请求到服务器,询问服务器是否允许该跨域请求。这个 OPTIONS 请求被称为“预检请求”。服务器在收到预检请求后,会根据请求头信息判断是否允许跨域,并在响应头中告知浏览器允许的请求方法、请求头等信息。如果服务器允许,浏览器才会发送真正的请求。
那么,哪些请求会被认为是“非简单”请求,需要进行预检呢?
-
请求方法非 GET, HEAD, POST: 例如 PUT, DELETE, PATCH, OPTIONS 等。
-
Content-Type 非以下几种:
application/x-www-form-urlencoded
multipart/form-data
text/plain
-
自定义请求头: 除了浏览器默认发送的一些请求头 (例如
Accept
,Accept-Language
,Content-Language
,Content-Type
(只限上面列出的三种),DPR
,Downlink
,Save-Data
,Viewport-Width
,Width
) 之外,如果设置了其他自定义请求头,则需要进行预检。
总结:
区分预检请求和简单请求的目的是为了在安全性和性能之间取得平衡。对于安全的简单请求,可以直接发送,避免额外的网络开销。对于可能存在安全风险的非简单请求,则需要通过预检请求进行确认,确保服务器允许该跨域请求,从而提高安全性。
通过这种机制,CORS 可以在保证安全性的前提下,尽可能地提高跨域请求的效率。