# 跨域(Options)请求介绍及解决方法

# 介绍

OPTIONS请求指method为OPTIONS的http请求。
通俗来说:它的作用是用于WEB服务器是否支持某些 header,也可以叫做预检请求(顾名思义:预先检测)。

程序员:跨域发送 http get { headers { xxx: abc } }
浏览器:等等,你这个请求有点奇怪,我去跟服务器确认下
浏览器:发送 http options { Access-Control-Allow-Headers: xxx }
       (你能接受 xxx header 吗?)
服务器:响应 http 200 ok { Access-Control-Allow-Headers: xxx}
       (可以的,来吧)
浏览器:发送 http get { headers { xxx: abc } }

通俗说法为了快速理解,并不十分精准

MDN定义 (opens new window)

HTTP 的 OPTIONS 方法 用于获取目的资源所支持的通信选项。

# OPTIONS请求负面影响

  1. 请求数据会多一次往返的时间消耗,具体消耗多长时间,取决与用户到服务器(端到端)的网络延迟,及服务的响应时长。
    通常在50ms~500ms之间。
  2. 后端程序员或一些nginx规则经常不处理OPTIONS请求,导致请求返回404,后续请求失败。

# 浏览器发起OPTIONS请求的条件

  1. 请求跨域,且2、3满足一个
  2. 请求方法不是:HEAD、GET、POST
  3. HTTP的头信息超出以下几种字段:
  Accept  
  Accept-Language  
  Content-Language  
  Last-Event-ID  
  Content-Type:仅限以下三个值
    application/x-www-form-urlencoded、multipart/form-data、text/plain
    (比如常见的 application/json 不在此列,所以会发送 options 请求)

参考: 阮一峰:跨域资源共享 CORS 详解 (opens new window)

我们遇到的OPTIONS请求几乎都是浏览器自行发起的。
为什么只有跨域请求浏览器才会自动发起OPTIONS请求
可以理解为,浏览器默认不同域名的服务器不是由你维护的,保险起见需要预先检查一下目标域名的服务器是否支持你自定义的 header 或 method

# 如何避免Options

方法一:配置网关转发规则,让前后端资源在同一域名下,通过 path 隔离前后端,从而避免跨域
方法二:将请求转换简单请求 (opens new window),比如自定义的 header 通过 query 参数传递

如果OPTIONS请求无法避免,设置缓存可尽量降低其负面影响,比如缓存一年:Access-Control-Max-Age: 31536000,这样后续相同URL的请求就不会发起OPTIONS请求了。
注意:缓存是针对URL的,URL一旦变化缓存会失效(比如URL中时间戳每次都变),会重新发起OPTIONS请求

💗 博主正处于裸辞待业状态,欢迎 商务合作 💗

相关文章

从 React 看前端 UI 代码范式革命

alt text 前言 本来打算写的主题是“我为什么讨厌 React Hooks API”,展开聊聊“小甜甜”是如何变成“牛夫人”的,没想到越写越严肃:) React 是两次前端范式革命的引领者,至今仍有繁荣的社区和旺盛的创造力; React 多次天才又激进的创新,一些想法被借鉴改良、一些引发广泛质疑,大部分是被认同和接受的; ...

一句话总结:TS 何时选择 interface 或 type

用 interface 描述类型的结构,用 type 描述类型关系。 有点编程基础中数据结构与算法的味道。 结构即是类型的属性集合 // 如 Point3D 的属性集合: x, y, z。 interface Poi ...

JS 定时器时长控制细节

背景 JS 最常使用 setTimeout、setInterval 来延迟或定时循环执行函数,通常会传递第二个参数来控制延迟或间隔执行的时间。 但开发者必须意识到函数执行时间并非精确地符合预期,在以下场景中它会超出你的预期 CPU 繁忙(主线程被长时间占用),JS 无法按开发者设定的预期时间延迟函数 定时器过于频繁地执行(第二个参数 < 4),达到一定 ...

JS 多线程并发

[[toc]] 为什么需要并发 我们常听说 JS 是单线程模型,即所有代码都在主线程中执行的。 如果某些任务计算量较大,将阻塞主线程,UI 界面轻则掉帧、重则卡死。 // 提示:本文所有代理均可复制到浏览器控制台中执行,验证效果 // ...

系统化学习 TS 类型系统

目的:快速、系统性的入门 TS 类型系统 [[toc]] 前言 TS 是什么? TS 是 JS 的超集, TS = JS + 类型系统 为了描述如此复杂(由于 JS 语言的灵活性/复杂性)的类型信息,类型系统表现出非常明显的编程语言特性。 以学习编程语言的方式,来学习 TS 类型系统 关键字/符号 类型: boolean, number, stri ...

单测(Unit Test)技巧

前言 本文目的是提高编写单测的效率,适合于有一定单测编写经验,但被单测困扰的同学。 后文的示例都在 unit-test-examples 仓库中。 单测的意义与价值 单测本质:将测试行为及结果固化下来,自动检查被测试代码的运行结果是否符合期望。 单测是一 ...

compilerOptions字段详解

{ "compilerOptions": { /* 基本选项 */ "target": "es5", // 指定 ECMAScript 目标版本: 'ES3' (default), 'ES5', 'ES6'/'ES2015', 'ES2016', 'ES2017', or 'ESNEXT' "module": ...

JS 正则表达式基础

前言 个人经验,正则是一个前期少量投入,回报超高的技能点。 其适用范围非常广泛,如批量文本处理、源码替换、程序中逻辑判断等等。 本文只介绍常用的基础知识、技巧,让初学者快速掌握大部分日常所需的正则知识。目标是 5 分钟内可逐字读完,10 分钟内可把例子都动手实践一 ...

JS优缺点

回顾上两期 优点(简单) 对象 链(原型链 & 作用域链) 一切都是对象(包括函数),构建世界的原料,越少越简单、灵活。 jimu 观察者模式,例: class Observer { constructor() { this.subscribe ...

JS 数据处理

[[toc]] 分享目标 JS 数据处理技巧速成 让你感叹:JS 还可以这样写 基础 实践原则 数据处理时,尽量避免创建临时变量(特别是 let)、修改参数、改变外部引用、for、if 等 分离 数据处理 与 副作用(DOM 操作、存储、网络请求等)代码 数据处理指:数值计算和数据结构变换。 第一点:如何避免? **1. 熟 ...