深浅主题
跨域与 Cookie 丢失
问题现象
请求在 Network 中成功但 JS 读取失败,预检 OPTIONS 被拒绝,或登录后下一次请求仍显示未登录。
适用环境
浏览器 Fetch、跨源 API、HTTPS;涉及跨站 Cookie 时关注浏览器隐私策略。
本文是可复用的排障示例,不代表某次个人生产事故。命令中的名称、账号和数据均为示例,执行前请替换为已确认的目标。
复现或诊断步骤
- 比较页面与 API 的协议、主机、端口;跨源与跨站不是同一概念。
- 在 Network 查看 OPTIONS 响应和实际请求,确认 Cookie 是否发送、Set-Cookie 是否被浏览器拒绝。
- 在 Application 检查 Domain、Path、SameSite、Secure 和到期时间,不复制真实会话值到工单。
原因分析
带凭据的 CORS 不能使用 Access-Control-Allow-Origin: *。客户端 credentials、服务端允许凭据和 Cookie 属性必须同时正确。跨站场景即使配置 SameSite=None; Secure,也可能被第三方 Cookie 策略阻止。
修复示例
js
const response = await fetch('https://api.example.com/profile', {
credentials: 'include',
headers: { Accept: 'application/json' }
})
if (!response.ok) throw new Error('HTTP ' + response.status)
const profile = await response.json()
// 服务端应按允许列表返回精确 Origin,并设置 Vary: Origin
// Access-Control-Allow-Credentials: true优先采用同源反向代理减少跨站依赖。确需跨源时配置精确 Origin 允许列表和允许的方法、请求头;OPTIONS 不应被普通登录过滤器拦截。Cookie 保留 HttpOnly,并结合 CSRF 防护评估凭据请求。
验证方法
用正常窗口和启用第三方 Cookie 限制的窗口分别登录、刷新和退出。确认恶意 Origin 不获授权,预检成功不代表实际响应的 CORS 头正确。
常见误区
mode:no-cors 只会得到不可读的 opaque 响应。不要为解决调试问题关闭浏览器安全策略,也不要移除 HttpOnly 后把令牌写到控制台。