为什么浏览器发送的 OPTIONS 请求没有携带 Cookie? 法霞 提问于 2026-02-27 22:41:16 阅读 35 前端 我在做跨域请求时发现,预检请求(OPTIONS)好像没带 Cookie,但正式请求却有。这是为啥? 我用的是 fetch 发请求,设置了 credentials: 'include',但 OPTIONS 请求在 DevTools 里看请求头根本没有 Cookie 字段,导致后端校验失败。 我来解答 赞 11 收藏 分享 生成中... 手机扫码查看 复制链接 生成海报 反馈 发表解答 您需要先 登录/注册 才能发表解答 2 条解答 丽红(打工版) Lv1 这其实是浏览器的行为,预检请求 OPTIONS 本来就不会带 Cookie。预检请求是浏览器自动发起的,它的作用就是询问服务器当前请求是否被允许,所以只包含最基本的 CORS 头信息。 你用 fetch 设置了 credentials: 'include' 是对的,但要注意后端也要配合。在处理实际请求时,服务端需要设置 Access-Control-Allow-Credentials: true 这个响应头。 另外别忘了配置正确的 Access-Control-Allow-Origin,它必须是具体的源地址,不能是通配符 * 。如果这些都设置了,正式请求就会带上 Cookie。 最后提醒下,如果你用的是 Nginx 做反向代理,记得检查 proxy_set_header 配置,有时候代理层会把 Cookie 给弄丢。 fetch('https://example.com/api', { method: 'POST', credentials: 'include', // 其他配置 }) // PHP 示例 header("Access-Control-Allow-Origin: https://yourdomain.com"); header("Access-Control-Allow-Credentials: true"); 这个机制设计上有点烦人,不过确实保护了安全性,虽然调试的时候挺让人头疼的。 回复 点赞 2026-03-27 19:11 书生シ利利 Lv1 这属于正常现象,不是你的代码问题。 OPTIONS 预检请求是浏览器自动发出的,目的是询问服务器"我能不能发正式请求"。按照 CORS 规范,预检请求不应该携带 Cookie、认证信息这些敏感数据,所以浏览器压根就不会把 Cookie 带上。 问题出在你后端拦截器上。后端不应该对 OPTIONS 请求做登录校验,应该直接放行。 以前踩过这个坑,后端拦截器代码大概长这样,你照着改: @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // OPTIONS 请求直接放行,不校验 if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin")); response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization"); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setStatus(HttpServletResponse.SC_OK); return true; } // 其他请求才做登录校验 String token = request.getHeader("Authorization"); // 校验逻辑... return true; } 关键点就两个: 第一,OPTIONS 请求必须放行,别让它走登录校验逻辑。 第二,响应头里 Access-Control-Allow-Credentials 要设为 true,Access-Control-Allow-Origin 不能写 *,必须写具体的域名,否则带 Cookie 的正式请求也会失败。 前端你的 credentials: 'include' 设置没问题,不用改。 回复 点赞 1 2026-02-28 15:03 加载更多 相关推荐 2 回答 54 浏览 为什么浏览器发送的POST请求变成了OPTIONS? 我在用 fetch 发送 POST 请求到后端接口,结果浏览器自动先发了个 OPTIONS 请求,而且我的 POST 根本没发出去,这是为啥? 我试过加了 Content-Type: applicat... 一丽君 前端 2026-03-26 20:43:19 1 回答 32 浏览 为什么浏览器发了 OPTIONS 请求却没发真正的 POST 请求? 我用 fetch 发一个跨域 POST 请求,结果只看到浏览器自动发了个 OPTIONS 预检请求,但后续的 POST 根本没发出去。后端也确认没收到 POST,控制台也没报错,就是卡住了。我试过加 ... シ利君 前端 2026-03-08 20:46:21 2 回答 30 浏览 为什么我的跨域请求总是先发一个 OPTIONS 请求? 我在前端用 fetch 调后端接口,明明只是发个 POST 请求,浏览器却先自动发了个 OPTIONS 请求,而且有时候还失败。后端同事说这是 preflight,但我没加什么特殊 header 啊,... 公孙瑞瑞 安全 2026-03-30 23:18:15 1 回答 45 浏览 Access-Control-Allow-Methods 设置后为什么 OPTIONS 请求还是失败? 我在前端用 fetch 发了个 POST 请求到后端接口,但浏览器先发了个 OPTIONS 预检请求,结果返回 405。后端明明在响应头里加了 Access-Control-Allow-Methods... 设计师新玲 安全 2026-03-12 12:13:19 2 回答 51 浏览 为什么浏览器发了 OPTIONS 请求却没发真正的 POST 请求? 我在用 React 调后端接口时,发现控制台里只看到一个 OPTIONS 请求,但我的 POST 请求根本没发出去,这是为啥?后端同事说跨域配置没问题,但我本地开发时就是请求失败。 我试过加 head... ___树泽 前端 2026-02-26 05:18:19 2 回答 78 浏览 Postman 中如何正确发送带 Cookies 的请求? 我在用 Postman 调试一个需要登录态的接口,后端返回了 Set-Cookie,但后续请求好像没自动带上 Cookie。我手动在 Headers 里加了 Cookie 字段也不行,是不是哪里配置错... 书生シ静静 工具 2026-03-02 19:49:26 1 回答 84 浏览 为什么Vue的POST请求触发OPTIONS预检却报403禁止访问? 我在Vue项目里用axios发POST请求给后端接口,控制台突然跳出CORS错误,显示OPTIONS请求返回了403。明明之前GET请求没问题啊,搞不懂为啥这次要先发OPTIONS? 代码就是简单的表... 夏侯司卿 安全 2026-02-19 02:07:26 2 回答 62 浏览 SameSite=Lax设置后,跨域请求携带Cookie失效怎么办? 我在项目中设置了Cookie的SameSite=Lax和Secure属性,但跨域请求到第三方支付接口时,Cookie没有被携带,导致登录失效。后端返回的Set-Cookie头看起来没问题,前端请求也用... Top丶颖杰 前端 2026-02-16 10:49:45 2 回答 108 浏览 前端POST请求被漏洞扫描工具标记CSRF漏洞,但后端已加防伪cookie该怎么办? 我在开发登录功能时,前端用axios发送POST请求,后端已通过nginx设置了Csrf-Token cookie且验证了请求头中的token。但最近漏洞扫描工具提示"缺少CSRF防护",明明后端已经... 爱学习的欢欢 安全 2026-01-28 22:49:30 2 回答 49 浏览 设置Cookie的Expires时间后,为什么浏览器仍然保留未过期的Cookie? 我之前给登录页面的cookie设置了过期时间为当前时间减1天,按理说应该立即失效,但用户退出登录后刷新页面,浏览器里这个cookie居然还在? 我检查过代码是这样写的:document.cookie ... Mr-艳珂 安全 2026-01-26 12:52:20
你用 fetch 设置了 credentials: 'include' 是对的,但要注意后端也要配合。在处理实际请求时,服务端需要设置 Access-Control-Allow-Credentials: true 这个响应头。
另外别忘了配置正确的 Access-Control-Allow-Origin,它必须是具体的源地址,不能是通配符 * 。如果这些都设置了,正式请求就会带上 Cookie。
最后提醒下,如果你用的是 Nginx 做反向代理,记得检查 proxy_set_header 配置,有时候代理层会把 Cookie 给弄丢。
这个机制设计上有点烦人,不过确实保护了安全性,虽然调试的时候挺让人头疼的。
OPTIONS 预检请求是浏览器自动发出的,目的是询问服务器"我能不能发正式请求"。按照 CORS 规范,预检请求不应该携带 Cookie、认证信息这些敏感数据,所以浏览器压根就不会把 Cookie 带上。
问题出在你后端拦截器上。后端不应该对 OPTIONS 请求做登录校验,应该直接放行。
以前踩过这个坑,后端拦截器代码大概长这样,你照着改:
关键点就两个:
第一,OPTIONS 请求必须放行,别让它走登录校验逻辑。
第二,响应头里
Access-Control-Allow-Credentials要设为true,Access-Control-Allow-Origin不能写*,必须写具体的域名,否则带 Cookie 的正式请求也会失败。前端你的
credentials: 'include'设置没问题,不用改。