Options请求是做什么用的?

OPTIONS 请求是 HTTP 协议中的一种方法,主要用于 CORS(跨域资源共享) 机制中的 “预检请求”(Preflight Request)

简单来说,它的作用是:浏览器在发送真正的跨域请求(如 POST、PUT、DELETE)之前,先向服务器“打听”一下:“我能不能发这个请求?你允许我用什么方法和头?”


🎯 核心作用:CORS 预检(Preflight)

当满足以下条件时,浏览器会自动发起 OPTIONS 请求:

  1. 跨域:请求的域名、端口或协议与当前页面不同。
  2. 非简单请求
    • 使用了 POST/PUT/DELETE/PATCH 等方法(GET/HEAD/POST 且 Content-Type 为简单类型除外)。
    • 自定义了请求头(如 Authorization, X-Custom-Header)。
    • Content-Type 不是 application/x-www-form-urlencoded, multipart/form-data, text/plain

🔄 流程演示

假设前端想跨域发送一个带 Authorization 头的 POST 请求:

  1. 第一步:浏览器自动发送 OPTIONS 预检请求

    OPTIONS /api/data HTTP/1.1
    Host: api.example.com
    Origin: https://my-website.com
    Access-Control-Request-Method: POST
    Access-Control-Request-Headers: Authorization, Content-Type
    

    ⚠️ 注意:这个请求不带任何业务数据(body 为空),只带询问信息。

  2. 第二步:服务器回复允许策略

    HTTP/1.1 204 No Content
    Access-Control-Allow-Origin: https://my-website.com
    Access-Control-Allow-Methods: POST, GET, OPTIONS
    Access-Control-Allow-Headers: Authorization, Content-Type
    Access-Control-Max-Age: 86400
    
  3. 第三步:如果预检通过,浏览器才发送真正的 POST 请求

    POST /api/data HTTP/1.1
    ... (携带真实数据和头)
    

❌ 如果服务器没正确响应 OPTIONS(比如返回 404 或缺少 CORS 头),浏览器会直接拦截后续的 POST 请求,并在控制台报错:
Access to fetch at '...' from origin '...' has been blocked by CORS policy


🛠 为什么需要它?

  • 安全保护:防止恶意网站随意向其他域发送危险请求(如删除数据、修改配置)。
  • 协商机制:让服务器明确告知浏览器哪些操作是允许的,避免无效请求浪费资源。

⚙️ 后端/Nginx 如何处理 OPTIONS

1. 后端框架(Node.js/Java/Python 等)

大多数现代框架(Express, Spring Boot, Django CORS 插件)会自动处理 OPTIONS

  • Express 示例
    app.options('*', cors()); // 启用所有路由的 OPTIONS 预检
    

2. Nginx 配置(手动处理)

如果你的后端不处理 OPTIONS,可以用 Nginx 直接拦截并返回 204:

location /api {
    # 如果是 OPTIONS 请求,直接返回 204 和 CORS 头
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '$http_origin';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
    }

    # 正常代理其他请求
    proxy_pass http://backend;
}

💡 关键点OPTIONS 请求不需要转发给后端应用(除非后端有特殊的逻辑),Nginx 直接响应即可,性能更好。


❓ 常见误区

误区 真相
“我要在代码里手动发 OPTIONS 请求” ❌ 不需要,浏览器会自动发,手动发反而奇怪
OPTIONS 请求失败了,我的业务逻辑没执行” ✅ 正常,因为预检都没过,根本轮不到业务逻辑
“我可以忽略 OPTIONS 请求” ❌ 对于复杂跨域请求,忽略会导致 CORS 报错
OPTIONS 也要查数据库/验权” ❌ 通常不需要,预检只是问权限,不应包含业务操作

✅ 总结

  • 用途:CORS 跨域预检,询问服务器“我能不能发这个复杂请求?”。
  • 触发者:浏览器自动触发(无需开发者代码干预)。
  • 响应要求:服务器必须返回 204 状态码及正确的 Access-Control-Allow-* 头。
  • 处理建议:在后端或 Nginx 层统一拦截处理,不要让它穿透到业务逻辑层。

如果你在开发中遇到 403 ForbiddenCORS error 且看到网络面板里有红色的 OPTIONS 请求,那就是预检失败了,重点检查后端的 CORS 配置或 Nginx 的 add_header 设置。

一般情况下,如果非同源地址发送请求的时候,有个预请求过程,预检请求是 options 请求。
一般浏览器会在三种情况下发送预检(preflight)请求:
·用到了非 GET、POST 的请求方法,比如 PUT、DELETE 等,会发预检请求看看服务端是否支持
·用到了一些非常规请求头,比如用到了 Content-Type,会发预检请求看看服务端是否支持
·用到了自定义 header,会发预检请求

posted @ 2026-03-05 15:52  龙陌  阅读(0)  评论(0)    收藏  举报