切换语言为:繁体

如何减少 options 请求

  • 爱糖宝
  • 2024-08-15
  • 2089
  • 0
  • 0

想要回答这个问题需要先明白什么是简单请求和非简单请求

浏览器请求方式可以划分为简单请求和非简单请求

简单请求

简单请求你可以理解为那些不会对服务器造成风险的请求。根据 CORS(跨源资源共享,Cross-Origin Resource Sharing) 的定义,简单请求必须满足以下条件:

  • 使用 GETPOSTHEAD 方法。

  • 仅包含少量特定的请求头部,如 AcceptAccept-LanguageContent-LanguageContent-Type(但只能是 application/x-www-form-urlencodedmultipart/form-datatext/plain)。

  • 不包含自定义的请求头部(即除了浏览器默认的上面那些)。

非简单请求

不满足简单请求的条件就是非简单请求

除了 GETPOST 和 HEAD 之外的其他 HTTP 方法都会导致请求变成非简单请求,例如:

  • PUT

  • DELETE

  • PATCH

任何不在简单请求头部列表中的头部,或者 Content-Type 不是 application/x-www-form-urlencodedmultipart/form-data 或 text/plain 的情况,都会导致请求变成非简单请求。例如:

  • Authorization

  • X-Custom-Header

  • Content-Type: application/json

非简单请求之前通常会触发浏览器发送一个 OPTIONS 预检请求,以确保服务器允许该跨域请求。

因此 options 请求就是预检请求

预检请求(Preflight Request)的意义

一句话解释:预检请求是浏览器在执行某些跨域请求之前,先发送的一种特殊的 HTTP 请求。它的主要目的是确保安全性,这个安全性针对服务端和客户端,服务端是防止恶意请求对服务器造成潜在的风险,客户端是保护用户的安全和隐私

非简单请求之前,预检请求先来询问服务器能否跨个域,就像是去朋友家做客,先打个电话问是否方便

  1. 服务器是否允许跨域请求:通过预检请求,浏览器可以确认服务器是否允许来自不同域名的请求。

  2. 允许的请求方法:预检请求可以告诉浏览器,服务器允许哪些 HTTP 方法(如 GETPOSTPUT 等)。

  3. 允许的请求头部:预检请求可以告诉浏览器,服务器允许哪些自定义的请求头部。

跨域请求

跨域请求是指从一个域(如 http://example.com)向另一个域(如 http://another-domain.com)发送的 HTTP 请求。无论请求是简单请求还是非简单请求,只要涉及到不同的域名、端口或协议,就属于跨域请求。因此跨域是不分简单请求和非简单请求的

非简单请求的跨域处理(预检请求的工作流程)

  1. 发送预检请求

当浏览器检测到一个非简单请求时,会先发送一个 OPTIONS 请求到服务器,询问服务器是否允许该实际请求。这个预检请求包含以下信息:

  • 请求方法(如 PUTDELETE 等)

  • 请求头部(如 Content-TypeAuthorization 等)

  1. 服务器响应预检请求

服务器收到预检请求后,需要返回一个响应,告诉浏览器它是否允许这个跨域请求。响应中包含以下信息:

  • 允许的来源(Access-Control-Allow-Origin

  • 允许的方法(Access-Control-Allow-Methods

  • 允许的头部(Access-Control-Allow-Headers

  1. 发送实际请求

如果服务器允许该请求,浏览器才会继续发送实际的请求

  1. 服务器响应实际请求

服务器处理实际请求,并返回响应

即使是简单请求,如果是跨域的,浏览器仍然会进行一些安全检查,但不会发送预检请求。

回归本文主题,回答之前你是否好奇明明预检请求是为了确保服务器和用户的安全,为何还要减少它?

options 请求过多带来的问题

  • 性能损耗:OPTIONS 请求是额外的网络开销。虽然通常不会带来显著的性能问题,但在高流量的应用中,大量的 OPTIONS 请求可能会增加服务器负担和网络延迟。

  • 用户体验:虽然 OPTIONS 请求本身很快(通常是几 ms ),但如果它们频繁出现或处理缓慢,可能会间接影响用户体验。减少这些请求可以确保实际的业务请求更快地得到响应。

  • 服务器负担:每个 OPTIONS 请求都需要服务器进行处理,并返回相应的 CORS 头部。这可能会增加服务器的负担,尤其是在处理大量预检请求时。优化这些请求有助于减少服务器的计算和网络开销。

如何减少 options 请求呢

  1. 尽量使用简单请求

从根源上看,浏览器不会对符合条件的 简单请求 发起 OPTIONS 预检请求,因此去使用简单请求

  1. 限制使用自定义头部

为了避免触发 OPTIONS 请求,尽量避免在请求中使用自定义头部。自定义头部会使请求成为非简单请求,从而触发 OPTIONS 预检请求。

  1. 使用 Content-Type 限制

如果你使用 POST 请求,可以通过限制 Content-Type 头部来避免 OPTIONS 请求。允许的 Content-Type 包括:

  • application/x-www-form-urlencoded

  • multipart/form-data

  • text/plain

如果你使用其他类型的 Content-Type,如 application/json,则会触发 OPTIONS 请求。

  1. 优化请求模式

尽量将请求方式设计得更简洁,避免复杂的跨域场景。如果可能,将请求合并为较少的 API 调用,减少跨域请求的次数。

  1. 服务器端配置

虽然前端没有直接控制 OPTIONS 请求,但在服务端,你可以通过优化 CORS 配置来处理 OPTIONS 请求。确保服务器对预检请求的响应快速且高效,以减少对前端性能的影响。

  1. 使用同域名资源

如果可以,尽量将前端和后端部署在同一域名下。这样可以避免跨域请求,完全不需要 OPTIONS 请求。

总结

想要减少 options 请求数量,主要可以通过确保请求满足简单请求的条件来避免预检请求,或者优化请求设计和头部使用

面试官问这个问题想必大部分人都是懵逼状态,因为你可能没有想过二次请求带来的问题,想要避免他就需要清楚 options 请求的发生条件

0条评论

您的电子邮件等信息不会被公开,以下所有项均必填

OK! You can skip this field.