分分钟搞明白高频面试题:OPTION 请求

269 阅读4分钟

OPTION 请求的作用

关于浏览器的 同源策略(Same-Origin Policy)长话短说:

同源策略出于安全考虑,限制了不同源(即不同的协议、域名或端口)之间的资源交互。这是为了防止恶意网站访问或篡改另一个源的数据。

然而,随着Web应用的发展,经常需要从不同的源(例如API服务)获取数据,于是 CORS(Cross-Origin Resource Sharing 跨域资源共享)机制就诞生了

CORS 允许服务器通过设置特定的HTTP响应头来决定哪些源可以访问它的资源,比如:Access-Control-Allow-OriginAccess-Control-Allow-MethodsAccess-Control-Allow-Headers 等等

OPTION 请求 就是用来询问服务器是否允许该跨源请求的。这样做可以过滤掉不被服务器允许的请求,从而减少不必要的网络通信和潜在的安全风险。通过这种方式,CORS机制确保了跨源请求的安全性,同时为服务器提供了灵活的控制手段。

所以你可以用一句话概括 OPTION 请求 的作用: OPTION 请求 就是为了询问服务器是否允许此次的跨域请求。

什么情况下会发起 OPTION请求

这里要明确两点:

  1. 并不是所有的post请求都会发起 OPTION 请求 的,我发现很多人都认为只要是post请求都会发 OPTION 请求
  2. 并不是跨域请求都会发起 OPTION 请求

只有同时满足下面两个条件时,浏览器才会自动发起 OPTION 请求

  1. 跨域请求
  2. 非简单请求

什么是跨域请求

请求的目标资源与发起请求的页面的源(协议、域名、端口)不同,就是跨域请求。

什么是简单请求

查看 W3C(World Wide Web Consortium 万维网联盟) 可知,满足下面所有条件者,即是简单请求

  • 使用GET、HEAD或POST方法
  • 不包含非CORS安全列表的自定义请求头,CORS安全列表中的头包括:
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type(但有限制,具体往下看)
  • 如果是POST请求,Content-Type头必须是以下三个值之一
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

为什么不是所有的请求都发送 OPTION 请求

如果所有请求都发一个 OPTION 请求,又会出现一些问题,比如说:

  • 性能问题:每个请求之前都需要发送一个额外的OPTIONS请求,这会导致网络延迟增加。
  • 服务器负担:大量的OPTIONS请求会增加服务器的负担,需要处理更多的请求,这可能导致服务器资源的浪费,尤其是在高流量的情况下。
  • 用户体验:对于用户来说,每次请求都需要等待预检完成,这会导致应用的响应时间变长,影响用户体验。

所以基于上面几个问题 CORS 把请求分为 简单请求非简单请求,其中 简单请求 被认为对服务器是安全的,并且不会引起对服务器的未授权访问或数据的意外更改,简单请求特性使得它们不需要通过预检来确认服务器的CORS策略,从而简化了跨源请求的处理流程。

OPTION 请求的实现原理

OPTIONS请求在CORS(跨源资源共享)中的实现原理涉及浏览器和服务器之间的交互。以下是详细的步骤和原理:

  1. 浏览器检测请求类型

    • 当浏览器发现一个跨源AJAX请求(如使用XMLHttpRequestfetch),它会首先检查这个请求是否为简单请求。
  2. 发送预检请求

    • 如果请求是非简单请求,浏览器会先发送一个OPTIONS请求到服务器。这个预检请求目的是询问服务器是否允许实际的跨源请求。
  3. 预检请求的请求头

    • 预检请求会包含以下请求头:
      • Access-Control-Request-Method:声明实际请求将使用的HTTP方法。
      • Access-Control-Request-Headers(如果需要):声明实际请求将使用的非CORS安全列表的请求头。
  4. 服务器处理预检请求

    • 服务器接收到OPTIONS请求后,会检查请求头中的Access-Control-Request-MethodAccess-Control-Request-Headers,然后根据内部配置的CORS策略来决定是否允许实际的请求。
    • 服务器的响应会包含以下CORS相关的响应头:
      • Access-Control-Allow-Origin:指定允许的源。
      • Access-Control-Allow-Methods:指定允许的HTTP方法。
      • Access-Control-Allow-Headers:指定允许的请求头。
      • Access-Control-Max-Age:预检请求结果的缓存时间。
      • Access-Control-Allow-Credentials:是否允许发送凭证。
  5. 浏览器处理预检响应

    • 浏览器检查OPTIONS请求的响应头,如果服务器允许跨源请求,则浏览器会记住这个决定,并在一定时间内(由Access-Control-Max-Age决定)缓存这个结果,然后发起真实请求
    • 如果服务器不允许跨源请求,浏览器会阻止实际的请求,并显示错误。