Ainul Ξ Creative Dev

Ainul Ξ Creative Dev

Product-focused software engineer.
twitter
tg_channel

CORS中的预检请求

只有在浏览器认为请求可能会导致服务器端变异时,才会对跨域请求进行预检。如果您进行跨域的 XMLHttpRequest / fetch 请求,它将被归类为以下两种类型之一:“简单请求” 或 “预检请求”。

简单请求是指那些(按照惯例)可以通过实际请求来确定 CORS 策略的请求。我说 “按照惯例”,是因为 REST/HTTP 并不强制要求您只能在 GET 请求上进行读取,或者 PUT 将创建或替换,这只是一种约定。

无论如何,如果您的请求使用 HEAD / GET 方法,浏览器可以假设在处理此请求时,源服务器不会进行任何变异,因此它只会在实际请求的响应中查找 Access-Control-Allow-Origin 头部,也就是说 CORS 策略是从实际请求中推断出来的。这被认为是安全的,并且可以节省一次往返。

然而,对于 PUT / DELETE 请求,发送实际请求可能会触发服务器端的变异(例如在数据库中创建或删除行),因此浏览器需要确保在发送实际请求之前,允许发起此请求的源。它无法通过实际请求来推断 CORS 策略,因为这样做会违背 CORS 的目的 - 源可以在没有明确许可的情况下对主机进行变异。当然,源可能无法看到主机的响应,但损害已经造成。这就是为什么浏览器必须 “预检” 实际请求,也就是发送一个单独的 (OPTIONS) 请求,明确询问主机是否允许发送所打算发送的请求。这个(预检)OPTIONS 请求具有 Access-Control-Request-Method 头部,描述了实际请求将使用的方法,以及 Access-Control-Request-Headers 头部,列出了实际请求将具有的头部。只有当主机服务器表示允许源使用 Access-Control-Request-Method 中的方法和 Access-Control-Request-Headers 中的头部发送请求时,才会发送实际请求。

是否预检请求的决定完全由客户端(在大多数情况下是 Web 浏览器)决定。它尽力在 CORS 协议的范围内尽量不发送额外的请求。不幸的是,这个决定不仅仅基于请求方法,还有可能导致甚至 GET 请求也需要进行预检的边界情况。

MDN 的 CORS 文档实际上是一篇很好的阅读材料,详细介绍了浏览器如何决定是否需要对请求进行预检。

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。