因为 document.cookie 无法删除 httponly cookie,后端必须通过 set-cookie 响应头覆盖原 cookie(同名、同 path/domain/secure/httponly 属性),并设 max-age=0 或 expires 过期,前端还需携带 credentials 发起注销请求。

点击注销按钮后 Cookie 还在,为什么?
因为 document.cookie 只能删自己设的、同源、且没设 HttpOnly 的 Cookie;而服务端发的带 HttpOnly 的认证 Cookie(比如 sessionid),前端根本读不到、也删不掉——这是浏览器安全限制,不是代码写错了。
后端必须设置 Set-Cookie 响应头来清 Cookie
注销接口(如 /api/logout)返回时,后端要主动下发一个覆盖式 Set-Cookie 头,把原 Cookie 的值设为空、过期时间设为过去,并保持路径(Path)、域名(Domain)、安全标记(Secure)等属性和登录时一致,否则浏览器不认。
常见错误配置:
-
Set-Cookie: sessionid=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Path=/; Domain=example.com; Secure; HttpOnly✅(属性匹配) -
Set-Cookie: sessionid=; Path=/api/❌(路径不一致,原 Cookie 是Path=/,这个不会覆盖) - 漏掉
Domain或Secure(HTTPS 站点下必须带Secure,否则浏览器拒绝写入)
前端发注销请求时得带 credentials
如果用 fetch,必须显式加 credentials: 'include',否则浏览器不传 Cookie,后端收不到会话上下文,也就没法生成正确的 Set-Cookie 响应头。
示例:
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
fetch('/api/logout', {
method: 'POST',
credentials: 'include',
headers: { 'Content-Type': 'application/json' }
})
用 axios 的话,默认不带凭证,得配 withCredentials: true;Vue 项目里如果用了全局 axios.defaults.withCredentials = true,反而可能在非鉴权请求里多传 Cookie,引发 CORS 预检失败。
登出后跳转前要不要手动删前端 Cookie?
只删非 HttpOnly 的 Cookie 有意义,比如存了用户昵称的 username;但删 sessionid 这类 HttpOnly Cookie 是徒劳的——document.cookie 根本看不见它,赋值无效。
更关键的是:别依赖前端“删干净了再跳转”。正确顺序是 —— 先发注销请求(触发后端清 Cookie),等响应成功后再跳转。否则用户可能跳到登录页,但旧 Cookie 还在,刷新一下又自动登录了。
容易被忽略的一点:有些框架(如 Next.js、Nuxt)的客户端跳转(router.push)默认不等待异步操作完成。必须 await fetch(...) 后再跳,不能只写 fetch(...).then(() => router.push(...)) —— Promise 被丢弃,跳转发生在响应到达前。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!








