浏览器预检请求

在 web 开发时遇到 preflight CORS 跨域错误,如下图所示

所谓 preflight CORS,就是在使用跨域请求时,浏览器会先发送一个预检请求,也被称为 OPTIONS 请求,来确认服务器是否支持特定的请求方法、请求头、以及是否允许跨域请求。

本文来分析分析这个预检请求到底有啥用,以及为什么会出现跨域失败的情况。

什么是预检请求?

预检请求是浏览器在发送跨域请求时,在正式请求之前,向服务器发送的一个 HTTP OPTIONS 请求。预检请求的主要目的是为了确定服务器是否支持特定的请求方法、请求头、以及是否允许跨域请求。预检请求的响应中包含了支持的请求方法、请求头以及是否允许跨域请求的信息,如果服务器支持这些请求,则浏览器才会发送真正的请求。

所以,如果出现预检请求跨域失败的情况,一般可以通过以下几个方面进行排查:

  • 服务端是否支持预检请求;
  • 服务端是否支持特定的请求方法、请求头、以及是否允许跨域请求。
  • 服务端是否正确返回了预检请求的响应。

为什么要有预检请求?

在 Web 开发中,由于浏览器的同源策略限制,跨域请求是一个很常见的问题。如果没有预检请求,浏览器就不能确定服务器是否支持特定的请求方法、请求头、以及是否允许跨域请求。这时浏览器会发出一个简单请求(比如 GETPOST 请求),服务器会拒绝该请求并返回错误信息。为了解决这个问题,引入了预检请求机制,用来确认服务器是否支持跨域请求,并根据响应信息决定是否发送真正的请求。

触发预检请求的条件

当满足以下条件时,浏览器会触发预检请求:

1、请求方法不是 GETHEADPOST 中的一种;

2、只能使用安全的请求头;

请求头 说明
Accept 指定客户端能够接收的内容类型
Accept-Language 指定客户端能够接收的语言
Content-Language 指定请求体中的语言
DPR 指定设备的像素比
Downlink 指定设备的下行速度
Save-Data 指定是否启用节省数据模式
Viewport-Width 指定设备的视口宽度
Width 指定设备的屏幕宽度
Content-Type 指定请求体的内容类型,只能使用 application/x-www-form-urlencodedmultipart/form-datatext/plain 中的一种

3、发送的请求数据是不可序列化的数据类型,比如 BlobFile 等。

预检请求的响应

当浏览器发送预检请求时,服务器需要返回以下信息:

  • Access-Control-Allow-Origin:指定允许跨域访问的域名;
  • Access-Control-Allow-Methods:指定允许的 HTTP 方法;
  • Access-Control-Allow-Headers:指定允许的请求头;
  • Access-Control-Allow-Credentials:指定是否允许发送 Cookie;
  • Access-Control-Max-Age:指定响应缓存时间。

如果服务器返回的信息不符合要求,浏览器将不会发送真正的请求,而是返回一个错误信息。

预检请求的缓存

由于预检请求的响应信息是不变的,所以可以进行缓存。服务器可以在响应中添加 Access-Control-Max-Age 头信息,来指定响应的缓存时间,避免重复发送预检请求。

预检请求的限制

预检请求可能会对性能产生一定的影响,因为每次跨域请求都需要发送一个额外的预检请求。为了避免这个影响,可以通过以下几个方面进行优化:

  1. 使用简单请求:对于满足条件的请求(请求方法为 GETHEADPOST,没有自定义请求头),可以使用简单请求来避免预检请求。
  2. 减少跨域请求:尽量减少跨域请求的次数,可以通过将静态资源放在同一域名下,或者使用 CDN 来提高性能。
  3. 缓存预检请求的响应:可以使用 Access-Control-Max-Age 头信息来缓存预检请求的响应,避免重复发送预检请求。
  4. 减少请求头的使用:尽量减少使用自定义请求头,避免触发预检请求。

结语

预检请求是解决跨域请求的一个重要机制,它可以确保浏览器发送的请求是安全的,并且服务器也能够正确地处理这些请求。预检请求虽然会对性能产生一定的影响,但可以通过减少跨域请求、缓存预检请求的响应、减少请求头的使用等方式进行优化,提高性能。合理的使用预检请求,可以帮助我们更好地解决跨域请求的问题。

相关推荐
Wect2 天前
浏览器缓存机制
前端·面试·浏览器
FliPPeDround6 天前
浏览器扩展 E2E 测试的救星:vitest-environment-web-ext 让你告别繁琐配置
e2e·浏览器·测试
SuperEugene6 天前
浏览器存储:localStorage / sessionStorage / cookie 应该怎么用
前端·javascript·面试·浏览器
宁雨桥6 天前
浏览器渲染原理
前端·浏览器·原理
YZ0998 天前
2026年如何批量保存小红书作者主页的视频、图片和文案?
经验分享·浏览器·插件
程序员ys8 天前
网页白屏的原理与优化
前端·性能优化·浏览器
Wect10 天前
从输入URL到页面显示的完整技术流程
前端·面试·浏览器
NEXT0610 天前
从输入 URL 到页面展示的完整链路解析
网络协议·面试·浏览器
CappuccinoRose13 天前
CSS 语法学习文档(十五)
前端·学习·重构·渲染·浏览器
REDcker14 天前
Media Source Extensions (MSE) 详解
前端·网络·chrome·浏览器·web·js