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

embedded/2024/10/18 8:38:26/
http://www.w3.org/2000/svg" style="display: none;">

在浏览器的 HTTP 请求中,当我们使用 fetch API 或者 XMLHttpRequest 来进行跨域请求时,浏览器有时会发送一种称为 Preflight 的请求。这种请求是浏览器在实际发送跨域请求前,先与目标服务器进行的一次 “探测” 请求,以确认服务器是否允许这样的请求方式。Preflight 请求的存在是为了保障浏览器的安全性,确保跨域请求不会在没有服务器允许的情况下进行。

跨域资源共享(CORS)机制规定了当浏览器发起跨域请求时,某些条件下需要发送 Preflight 请求。这种探测性的请求使用 OPTIONS 方法发出,目标是向服务器询问,客户端接下来想要发送的实际请求是否被允许。
下面是一个例子:
https://img-blog.csdnimg.cn/img_convert/b8cf65b98823c1f40318c2a9fe0b6225.webp?x-oss-process=image/format,png" alt="" />

Preflight 请求的触发条件

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

  1. 当请求方法不是 GETPOSTHEAD,例如 PUTDELETE
  2. 当请求包含非标准的 HTTP 头部字段,比如自定义的 Authorization 头部,或者 Content-Type 不是 application/x-www-form-urlencodedmultipart/form-datatext/plain

下面是自定义头部字段触发 preflight 请求的一个例子:

https://img-blog.csdnimg.cn/img_convert/8a5ed71c04ea99348ed1024c64bb51c6.webp?x-oss-process=image/format,png" alt="" />

  1. 请求中涉及跨域资源时,尤其是涉及到敏感的操作时,浏览器会通过 Preflight 请求来确保服务器允许这些操作。

这种设计的初衷是为了防止跨域请求滥用,尤其是在涉及敏感数据的场景下,确保浏览器与服务器之间的交互安全。

Preflight 请求的流程

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

请求示例:

假设我们要向 https://api.example.com/data 发送一个跨域的 PUT 请求,并且需要携带自定义头部 X-Custom-Header。在实际发出 PUT 请求之前,浏览器会自动生成如下的 Preflight 请求:

http">OPTIONS /data HTTP/1.1
Host: api.example.com
Origin: https://client.example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header

其中,Access-Control-Request-Method 头部用来告诉服务器接下来会使用 PUT 方法,而 Access-Control-Request-Headers 则表明请求中会携带 X-Custom-Header 这个自定义头部。

服务器响应:

服务器接收到 Preflight 请求后,必须返回一个响应来告诉浏览器是否允许此类请求:

http">HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://client.example.com
Access-Control-Allow-Methods: GET, PUT, POST, DELETE
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 请求来自服务器端的响应的一个例子:

https://img-blog.csdnimg.cn/img_convert/13bb979dbe4bf47f8ea9c90a3b761139.webp?x-oss-process=image/format,png" alt="" />

Preflight 请求的使用场合

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

常见的使用场景包括:

  1. RESTful API 请求:当前端应用需要与其他域名下的 REST API 进行交互时,尤其是对资源进行 PUTDELETE 操作时,往往会触发 Preflight 请求。这些操作可能会修改服务器上的数据,因此需要确保安全。

    例如,一个前端应用需要向远程服务器发送数据更新请求,使用 PUT 方法更新用户信息。在这种场景下,Preflight 请求就会确保目标服务器允许跨域的 PUT 请求。

  2. 上传文件的操作:在表单上传文件时,如果使用 fetch API 或 XMLHttpRequest 并携带了非标准的头部,比如自定义的认证信息,通常会触发 Preflight 请求。浏览器需要确保服务器允许上传操作以及这些自定义的头部字段。

  3. 自定义认证头部的请求:很多应用在发起跨域请求时,需要在头部中携带如 AuthorizationToken 的自定义认证信息。由于这些头部字段并非标准字段,浏览器会先发送 Preflight 请求来探测服务器是否允许使用这些自定义头部。

Preflight 请求的实际案例

在实际开发中,有一个典型的例子是前端应用需要向第三方服务发送请求并带有认证信息。这种场景下的跨域请求常常会触发 Preflight 请求。

假设我们开发了一个电子商务应用,这个应用的后端服务托管在 https://api.shop.com,而前端页面托管在 https://shop.com。用户在购物时,前端需要向后端发送带有用户身份认证的请求,如以下场景:

  1. 用户在购物车页面点击结账,前端应用需要向后端 API 发送包含用户认证信息的请求,以确认用户是否已登录,且是否有购买权限。
  2. 请求方法为 POST,同时头部中带有 Authorization: Bearer token123 来验证用户身份。

此时,由于 Authorization 头部是非标准字段,且前端和后端的域名不同,这个请求会触发 Preflight 检查。

请求步骤:
  1. Preflight 请求
    浏览器会自动先发送一个 OPTIONS 请求,探测服务器是否允许发送带有 Authorization 头部的跨域请求:

    http">OPTIONS /checkout HTTP/1.1
    Host: api.shop.com
    Origin: https://shop.com
    Access-Control-Request-Method: POST
    Access-Control-Request-Headers: Authorization
    
  2. 服务器响应
    后端服务器接收到该请求后,会检查是否允许该跨域请求,并返回允许的结果:

    http">HTTP/1.1 204 No Content
    Access-Control-Allow-Origin: https://shop.com
    Access-Control-Allow-Methods: POST
    Access-Control-Allow-Headers: Authorization
    

    响应中,服务器明确告知浏览器允许该域名 https://shop.com 发起 POST 请求,并且允许使用 Authorization 头部。

  3. 实际请求
    在确认服务器允许跨域请求后,浏览器会继续发送实际的 POST 请求,包括认证信息:

    http">POST /checkout HTTP/1.1
    Host: api.shop.com
    Origin: https://shop.com
    Authorization: Bearer token123
    
使用 Preflight 请求的优化

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

  1. 服务器缓存 Preflight 响应:通过在响应中设置 Access-Control-Max-Age 头部,服务器可以告知浏览器在一定时间内不需要重复进行 Preflight 请求。这能显著减少不必要的 OPTIONS 请求,提升应用的性能。

    例如,服务器可以返回这样的响应,告知浏览器在未来 10 分钟内不需要重新发起 Preflight 请求:

    http">HTTP/1.1 204 No Content
    Access-Control-Allow-Origin: https://shop.com
    Access-Control-Allow-Methods: POST
    Access-Control-Allow-Headers: Authorization
    Access-Control-Max-Age: 600
    
  2. 减少复杂的请求:避免不必要的自定义头部字段,或者尽量使用简单的 GETPOST 请求,能够有效减少 Preflight 请求的触发。对于一些轻量级的操作,使用标准的请求方法和头部可以避免 Preflight 请求,从而提升效率。

结语

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


http://www.ppmy.cn/embedded/124131.html

相关文章

Linux卸载mysql

一、查看当前安装mysql情况,查找以前是否装有mysql rpm -qa|grep -i mysql二、停止MySQL服务 三、删除mysql库和文件 查找MySQL库 # 查找命令 find / -name mysql# 显示结果 /var/lib/mysql/var/lib/mysql/mysql/usr/lib64/mysql删除对应的mysql目录 rm -rf /v…

MATLAB智能优化算法-学习笔记(4)——灰狼优化算法求解旅行商问题【过程+代码】

灰狼优化算法(Grey Wolf Optimizer, GWO)是一种基于灰狼社会行为的元启发式算法,主要模拟灰狼群体的捕猎行为(包括围攻、追捕、搜寻猎物等过程)。多旅行商问题(Multi-Traveling Salesman Problem, mTSP)是旅行商问题(TSP)的扩展,它涉及多个旅行商(车辆)从一个起点城…

模型作为参数传入类的实例中进行训练

问:将模型当作一个参数传入一个类中,在类的内部对这个模型训练后,那么这个模型是否像“全局参数”一样更新了信息,即当在类之外调用这个模型时,模型参数已经更新了? 答:是的,将模型作…

python脚本实现Redis未授权访问漏洞利用

之前介绍过Redis未授权访问漏洞,本文使用python实现Redis未授权访问检测以及对应三种getshell。 1 测试环境准备 CentOS 7(192.168.198.66/24):安装 Redis 服务器并用 root 权限开启服务,关闭保护模式;安…

yolov11 部署瑞芯微rk3588、RKNN部署工程难度小、模型推理速度快

yolov8还没玩溜,yolov11又来了,那么部署也又来了。 特别说明:如有侵权告知删除,谢谢。 完整代码:包括onnx转rknn和测试代码、rknn板端部署C代码 【onnx转rknn和测试代码】 【rknn板端部署C代码】 1 模型训练 yolov1…

从0到1:企事业单位知识竞赛答题小程序迭代开发笔记一

背景调研 企事业单位知识竞赛答题小程序,在信息技术迅猛发展的时代,企业和事业单位在提升员工素质和知识水平方面面临着新的挑战。为了增强员工的学习积极性、提高团队凝聚力和整体素质,越来越多的单位开始组织知识竞赛活动。传统的知识竞赛…

R语言绘制面积图

面积图是一种数据可视化图表。它通过填充区域来展示数据随某个变量(如时间)的变化趋势及累积效果。面积图能清晰地呈现数据的上升、下降和波动情况,直观反映数据的大小关系。适用于多种领域,如经济数据分析展示 GDP 变化及产业贡献…

OpenCV-OCR

文章目录 一、OCR技术的基本原理二、OpenCV在OCR识别中的应用1.图像预处理2.文字区域检测3.OCR识别:4.后处理: 三、OCR识别示例代码四、注意事项 OpenCV-OCR主要涉及使用OpenCV库进行光学字符识别(OCR)的技术。OCR技术可以识别图像…