直接读写 document.cookie 极其麻烦,因需手动字符串拆分、正则匹配、编码解码及拼接完整属性(如 expires、secure、SameSite),稍错即失效或不安全。

直接读写 document.cookie 有多麻烦?
JavaScript 没有原生的 Cookie 操作 API,所有读写都靠字符串拼接和正则解析。每次读 document.cookie 返回的是一个用分号分隔的字符串(如 "a=1; b=2; path=/; HttpOnly"),你得自己拆、自己找、自己编码/解码。写入时还要手动拼 name=value; expires=...; path=...; secure; SameSite=Lax 等字段,漏一个就可能失效或不安全。
常见错误包括:encodeURIComponent 忘加导致中文乱码;expires 设成字符串而非 Date.toUTCString();SameSite 值写错(比如写成 "sameSite" 小写或拼错为 "Strictt");secure 在非 HTTPS 环境下仍启用导致写入失败。
实操建议:
- 读取单个 Cookie:用
document.cookie.split('; ').find(row => row.startsWith('mykey='))?.split('=')[1],但必须配合decodeURIComponent - 写入前务必检查协议:
location.protocol === 'https:'才设secure - 过期时间统一用
new Date(Date.now() + 86400e3).toUTCString()(1 天后),避免本地时区干扰
localStorage 和 sessionStorage 的核心区别在哪?
两者都是同步 API,但生命周期和作用域完全不同:localStorage 持久保存,除非手动调用 removeItem() 或清空浏览器数据;sessionStorage 仅限当前 tab 生命周期,关闭 tab 即销毁,且不同 tab 互不共享。
立即学习“Java免费学习笔记(深入)”;
它们都只支持字符串值,存对象必须先 JSON.stringify(),取出来要 JSON.parse()。没做 try/catch 容错的话,一旦字符串非法(比如被其他脚本污染),JSON.parse() 直接抛 SyntaxError,后续逻辑中断。
实操建议:
- 封装读写函数,自动处理序列化/反序列化和异常捕获
- 不要存敏感信息(如 token)到
localStorage—— XSS 一击即中 -
sessionStorage更适合临时表单草稿、向导步骤状态等“关掉就丢”的场景
为什么 Cookie + HttpOnly + Secure 仍是登录态首选?
因为 HttpOnly 能彻底阻断 JavaScript 访问(document.cookie 里看不到该 Cookie),配合 Secure(仅 HTTPS 传输)和 SameSite=Strict 或 Lax,可大幅降低 CSRF 和 XSS 盗用风险。而 localStorage 中的 JWT,只要页面存在任意 XSS 漏洞,攻击者一行 fetch('/api/user', {headers:{'Authorization': 'Bearer '+localStorage.getItem('token')}}) 就能盗走全部权限。
注意:SameSite=None 必须搭配 Secure,否则现代浏览器(Chrome 80+)会拒绝设置;Domain 属性若设为父域(如 Domain=example.com),子域(app.example.com)可共享,但要防跨子域污染。
实操建议:
-
后端设 Cookie 时显式声明
HttpOnly=true; Secure=true; SameSite=Lax - 前端 JS 只负责触发登录请求,不碰认证 Cookie 的读写
- 需要前端读取的非敏感配置(如用户偏好),可用另一个非
HttpOnly的 Cookie 或localStorage
第三方脚本和 CSP 对 Cookie / 存储的实际影响
如果页面引入了广告或分析 SDK,它们可能通过 document.cookie 读取你设的非 HttpOnly Cookie;更隐蔽的是,某些 SDK 会把 localStorage 数据发往外部域名,形成静默泄露。内容安全策略(CSP)虽不能阻止 Cookie 读写,但能限制脚本加载源,间接降低 XSS 风险。
例如,设了 Content-Security-Policy: script-src 'self',就能拦掉未授权的 CDN 脚本;但若你写了 script-src 'unsafe-inline',内联事件(如 onclick="alert(document.cookie)")依然可执行。
实操建议:
- 定期 audit
document.cookie输出,确认没有意外多出的键名 - 用
window.addEventListener('storage', ...)监听同域下其他 tab 对localStorage的修改(但监听不到跨域或 Cookie 变化) - 敏感操作(如支付)前,强制重新验证身份,别依赖长期存储的 token
真正难的不是怎么存,是怎么确保它不被不该拿到的人拿到——尤其是当你的页面混着 5 个第三方 SDK,又开了 eval() 的时候。











