什么是 HTTP 请求中的 preflight 类型请求

张裕  金牌会员 | 2024-10-7 04:39:24 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 509|帖子 509|积分 1527

在浏览器的 HTTP 请求中,当我们使用 fetch API 或者 XMLHttpRequest 来进行跨域请求时,浏览器有时会发送一种称为 Preflight 的请求。这种请求是浏览器在实际发送跨域请求前,先与目标服务器进行的一次 “探测” 请求,以确认服务器是否答应如许的请求方式。Preflight 请求的存在是为了保障浏览器的安全性,确保跨域请求不会在没有服务器答应的情况下进行。
跨域资源共享(CORS)机制规定了当浏览器发起跨域请求时,某些条件下需要发送 Preflight 请求。这种探测性的请求使用 OPTIONS 方法发出,目标是向服务器扣问,客户端接下来想要发送的实际请求是否被答应。
下面是一个例子:

Preflight 请求的触发条件

不是所有的跨域请求都会触发 Preflight 请求,浏览器会根据请求的类型和头部信息来决定是否需要预检。Preflight 请求通常在以下几种情况下触发:

  • 当请求方法不是 GET、POST 或 HEAD,例如 PUT、DELETE。
  • 当请求包含非尺度的 HTTP 头部字段,比如自定义的 Authorization 头部,或者 Content-Type 不是 application/x-www-form-urlencoded、multipart/form-data、text/plain。
下面是自定义头部字段触发 preflight 请求的一个例子:


  • 请求中涉及跨域资源时,尤其是涉及到敏感的操纵时,浏览器会通过 Preflight 请求来确保服务器答应这些操纵。
这种计划的初衷是为了防止跨域请求滥用,尤其是在涉及敏感数据的场景下,确保浏览器与服务器之间的交互安全。
Preflight 请求的流程

当浏览器决定某个跨域请求需要进行 Preflight,它会先向目标服务器发出一个 OPTIONS 请求,携带一些须要的头部信息,如 Access-Control-Request-Method 和 Access-Control-Request-Headers,用于告知服务器,客户端即将发送的请求的具体方法和头部信息。服务器通过相应来告知浏览器,是否答应如许的请求。
请求示例:

假设我们要向 https://api.example.com/data 发送一个跨域的 PUT 请求,并且需要携带自定义头部 X-Custom-Header。在实际发出 PUT 请求之前,浏览器会主动天生如下的 Preflight 请求:
  1. OPTIONS /data HTTP/1.1
  2. Host: api.example.com
  3. Origin: https://client.example.com
  4. Access-Control-Request-Method: PUT
  5. Access-Control-Request-Headers: X-Custom-Header
复制代码
其中,Access-Control-Request-Method 头部用来告诉服务器接下来会使用 PUT 方法,而 Access-Control-Request-Headers 则表明请求中会携带 X-Custom-Header 这个自定义头部。
服务器相应:

服务器吸取到 Preflight 请求后,必须返回一个相应来告诉浏览器是否答应此类请求:
  1. HTTP/1.1 204 No Content
  2. Access-Control-Allow-Origin: https://client.example.com
  3. Access-Control-Allow-Methods: GET, PUT, POST, DELETE
  4. Access-Control-Allow-Headers: X-Custom-Header
复制代码
服务器通过 Access-Control-Allow-Origin 来指定哪些源是答应访问的(这里是 https://client.example.com),通过 Access-Control-Allow-Methods 来列出答应的 HTTP 方法,并通过 Access-Control-Allow-Headers 来列出答应的头部字段。
下面是 Preflight 请求来自服务器端的相应的一个例子:

Preflight 请求的使用场合

Preflight 请求重要用于跨域场景下,特别是那些涉及到更复杂请求的场合,比如非 GET 或 POST 方法,或者请求中包含了额外的自定义头部。
常见的使用场景包括:

  • RESTful API 请求:当前端应用需要与其他域名下的 REST API 进行交互时,尤其是对资源进行 PUT 或 DELETE 操纵时,往往会触发 Preflight 请求。这些操纵大概会修改服务器上的数据,因此需要确保安全。
    例如,一个前端应用需要向远程服务器发送数据更新请求,使用 PUT 方法更新用户信息。在这种场景下,Preflight 请求就会确保目标服务器答应跨域的 PUT 请求。
  • 上传文件的操纵:在表单上传文件时,假如使用 fetch API 或 XMLHttpRequest 并携带了非尺度的头部,比如自定义的认证信息,通常会触发 Preflight 请求。浏览器需要确保服务器答应上传操纵以及这些自定义的头部字段。
  • 自定义认证头部的请求:许多应用在发起跨域请求时,需要在头部中携带如 Authorization 或 Token 的自定义认证信息。由于这些头部字段并非尺度字段,浏览器会先发送 Preflight 请求来探测服务器是否答应使用这些自定义头部。
Preflight 请求的实际案例

在实际开辟中,有一个典型的例子是前端应用需要向第三方服务发送请求并带有认证信息。这种场景下的跨域请求常常会触发 Preflight 请求。
假设我们开辟了一个电子商务应用,这个应用的后端服务托管在 https://api.shop.com,而前端页面托管在 https://shop.com。用户在购物时,前端需要向后端发送带有效户身份认证的请求,如以下场景:

  • 用户在购物车页面点击结账,前端应用需要向后端 API 发送包含用户认证信息的请求,以确认用户是否已登录,且是否有购买权限。
  • 请求方法为 POST,同时头部中带有 Authorization: Bearer token123 来验证用户身份。
此时,由于 Authorization 头部是非尺度字段,且前端和后端的域名差别,这个请求会触发 Preflight 查抄。
请求步骤:


  • Preflight 请求
    浏览器会主动先发送一个 OPTIONS 请求,探测服务器是否答应发送带有 Authorization 头部的跨域请求:
    1. OPTIONS /checkout HTTP/1.1
    2. Host: api.shop.com
    3. Origin: https://shop.com
    4. Access-Control-Request-Method: POST
    5. Access-Control-Request-Headers: Authorization
    复制代码
  • 服务器相应
    后端服务器吸取到该请求后,会查抄是否答应该跨域请求,并返答复应的结果:
    1. HTTP/1.1 204 No Content
    2. Access-Control-Allow-Origin: https://shop.com
    3. Access-Control-Allow-Methods: POST
    4. Access-Control-Allow-Headers: Authorization
    复制代码
    相应中,服务器明确告知浏览器答应该域名 https://shop.com 发起 POST 请求,并且答应使用 Authorization 头部。
  • 实际请求
    在确认服务器答应跨域请求后,浏览器会继续发送实际的 POST 请求,包括认证信息:
    1. POST /checkout HTTP/1.1
    2. Host: api.shop.com
    3. Origin: https://shop.com
    4. Authorization: Bearer token123
    复制代码
使用 Preflight 请求的优化

尽管 Preflight 请求保障了安全性,但在一些频仍的跨域请求场景下,这会带来额外的网络开销。为此,可以采用一些优化策略:

  • 服务器缓存 Preflight 相应:通过在相应中设置 Access-Control-Max-Age 头部,服务器可以告知浏览器在一定时间内不需要重复进行 Preflight 请求。这能明显减少不须要的 OPTIONS 请求,提升应用的性能。
    例如,服务器可以返回如许的相应,告知浏览器在未来 10 分钟内不需要重新发起 Preflight 请求:
    1. HTTP/1.1 204 No Content
    2. Access-Control-Allow-Origin: https://shop.com
    3. Access-Control-Allow-Methods: POST
    4. Access-Control-Allow-Headers: Authorization
    5. Access-Control-Max-Age: 600
    复制代码
  • 减少复杂的请求:制止不须要的自定义头部字段,或者尽量使用简单的 GET、POST 请求,可以或许有效减少 Preflight 请求的触发。对于一些轻量级的操纵,使用尺度的请求方法和头部可以制止 Preflight 请求,从而提升效率。
结语

Preflight 请求作为 CORS 机制的一部分,重要作用是确保跨域请求的安全性,尤其是在涉及非尺度请求时。通过 Preflight 请求,浏览器与服务器可以或许就请求的正当性达成共识,保护用户的数据安全。在实际应用中,理解 Preflight 请求的工作原理,并在符合的场景下进行优化,可以或许大大提升 Web 应用的性能和用户体验。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

张裕

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表