服务端通过set-cookie响应头写入cookie,浏览器自动识别存储并后续同源请求自动携带;需正确配置path、domain、max-age、secure、httponly、samesite等属性,且仅2xx响应有效,secure要求https,httponly禁止js访问。

服务端通过 Set-Cookie 响应头写入 Cookie,是浏览器自动识别并存储的标准机制。关键在于:服务端在 HTTP 响应中正确设置 Set-Cookie 头,浏览器收到后按规则保存,后续同源请求自动携带(除非被标记为 HttpOnly 或 Secure 等限制)。
服务端如何设置 Set-Cookie(以常见框架为例)
不同后端语言/框架写法略有差异,但本质都是向响应头写入 Set-Cookie 字段:
-
Node.js + Express:
res.cookie('name', 'value', { httpOnly: true, secure: true, sameSite: 'strict' });
或手动:res.setHeader('Set-Cookie', 'theme=dark; Path=/; HttpOnly; Secure; SameSite=Strict'); -
Python + Flask:
response.set_cookie('token', 'abc123', httponly=True, secure=True, samesite='Lax') -
Java + Spring Boot:
使用ResponseEntity或HttpServletResponse.addCookie(),如:Cookie cookie = new Cookie("lang", "zh-CN");<br>cookie.setPath("/");<br>cookie.setHttpOnly(true);<br>cookie.setSecure(true);<br>response.addCookie(cookie);
Set-Cookie 的关键属性必须写对
仅写 key=value 往往不够,实际部署中需关注以下属性:
-
Path:指定 Cookie 生效路径,默认为当前响应路径,常设为
/使其全站可用 -
Domain:控制哪些子域名可读取,如
Domain=.example.com允许api.example.com和www.example.com共享 -
Expires / Max-Age:决定过期时间;
Expires是绝对时间(GMT 格式),Max-Age是秒数(推荐优先用Max-Age) - Secure:仅在 HTTPS 连接中发送,生产环境必须开启
- HttpOnly:禁止 JavaScript 读取(防 XSS),适合存 token、session_id 等敏感信息
-
SameSite:缓解 CSRF,默认值逐渐变为
Lax;Strict最严,None需配合Secure
浏览器是否真的接收并存储了?怎么验证
写入成功 ≠ 浏览器一定存下,常见失败原因:
- 响应状态码不是 2xx(如 304、401)——多数服务器框架不会在非 2xx 响应中发送
Set-Cookie - 域名不匹配:服务端设置的
Domain与当前页面域名不符(例如后端域名为api.example.com,前端在test.com,且未正确配置Domain) - 协议不一致:设置了
Secure但当前是 HTTP 页面 - SameSite 冲突:比如跨站 POST 请求带
SameSite=Strict的 Cookie,会被浏览器丢弃 - 浏览器隐私设置或扩展拦截(如某些广告拦截插件会过滤第三方 Cookie)
验证方式:
– 打开浏览器开发者工具 → Application(或 Application → Cookies)标签页,查看对应域名下是否有新 Cookie;
– 查看 Network 面板中响应头,确认 Set-Cookie 是否存在且格式合法(无语法错误,如多空格、非法字符)。
注意:JavaScript 无法直接读取 HttpOnly Cookie
如果服务端设置了 HttpOnly,那么 document.cookie 将完全看不到该 Cookie —— 这是设计行为,不是 bug。此时 Cookie 只用于服务端校验(如 session 验证),前端无需、也不应尝试访问它。若前端确实需要某些配置值(如主题、语言),应由服务端在 HTML 或接口响应中显式返回,而不是依赖 JS 读取。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











