Evan Wang
Evan WangFrontEnd Developer
  • Evan Wang
    Evan WangFrontEnd Developer
  • 前端相关
  • 算法题
  • 日常笔记
  • Chat With AI

HTTP状态码
get和post的区别
三次握手_四次挥手
HTTPS加密过程
预检请求
HTTP各个版本的差异

  1. Articles
  1. More
  2. 5-预检请求.md
目录
一句话总结简单请求复杂请求
1693 字
约 5 分钟
更新于 2026/08/20

预检请求

一句话总结:

当浏览器发起跨域请求时,如果请求属于 “简单请求” 浏览器就直接发,如果属于 “复杂请求” ,浏览器会先自动发送一个 预检请求 (OPTIONS) 来询问服务器是否允许本次的跨域请求。

简单请求:

当发起跨域请求时,符合下面所有条件的请求,是简单请求:

  1. 请求方法是 GET / POST / HEAD
  2. 请求头只包含:
    • Accept
    • Range (只允许简单的范围,比如:byte=256- 或者 byte-127-255)
    • Accept-Language
    • Content-Language
    • Content-Type 并且值仅限于以下三者之一:
      • application/x-www-form-urlencoded,
      • multipart/form-data,
      • text/plain
  3. 请求中不会用
    • 自定义请求头 (比如: X-token)
    • application/json 类型的 POST
    • PUT 、DELETE 等方法
    • Credentials (携带 cookie)
  4. 请求中没有 ReadableStream 对象

简单请求示例:

fetch('https://api.example.com/data', {
  method: 'GET',
})
 
fetch('https://api.example.com/login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  body: 'username=admin&password=123'
})

复杂请求:

只要不满足简单请求的条件,就属于 “复杂请求“ , 浏览器会自动发一个 OPTIONS 请求,看服务端是否允许当前的跨域请求,如果服务端允许,再发送真正的请求。

fetch('https://api.example.com/data', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Custom-Header': 'abc' // 自定义头
  },
  body: JSON.stringify({ name: 'Jack' })
})
  • 浏览器会自动先发一个 OPTIONS 请求 (不带 body ),询问服务端是否支持这个自定义 header
  • 如果服务端返回了正确的 Access-Control-Allow-* 响应头,才会再发送 POST 请求。

预检请求: “需要预检的请求” 必须先使用 OPTIONS 方法发起一个预检请求到服务端,以获知服务器是否允许该实际请求。

“预检请求” 的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。

预检请求的相应结果一般包含下面几个响应头:

  • Access-Control-Allow-Origin: https://foo.example

    表明允许 https://foo.example 的域访问服务器的资源。

  • Access-Control-Allow-Methods: POST, GET, OPTIONS

    表明服务端允许客户端使用 POST、GET、OPTIONS 三种方法发起请求。

  • Access-Control-Allow-Headers: X-PINGOTHER, Content-Type

    表明服务端允许请求中携带 X-PINGOTHER, Content-Type 请求头(自定义请求头)。

  • Access-Control-Max-Age: 86400

    表明服务端给定了该预检请求可供缓存的时间长短,单位为 s , 默认值是 5s,在有效时间内,浏览器无需为同一请求再次发起预检请求。

注:

如果不是跨域请求,即使请求是复杂请求,浏览器也 不会 发出预检请求。

附:
跨域报错: 跨域报错: