为什么浏览器发送的 OPTIONS 请求没有携带 Cookie?

法霞 阅读 21

我在做跨域请求时发现,预检请求(OPTIONS)好像没带 Cookie,但正式请求却有。这是为啥?

我用的是 fetch 发请求,设置了 credentials: 'include',但 OPTIONS 请求在 DevTools 里看请求头根本没有 Cookie 字段,导致后端校验失败。

我来解答 赞 3 收藏
二维码
手机扫码查看
1 条解答
书生シ利利
这属于正常现象,不是你的代码问题。

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 要设为 trueAccess-Control-Allow-Origin 不能写 *,必须写具体的域名,否则带 Cookie 的正式请求也会失败。

前端你的 credentials: 'include' 设置没问题,不用改。
点赞 1
2026-02-28 15:03