横幅仅在用户未表态时显示,首次访问默认隐藏;通过 document.cookie 或 localStorage 读写 cookie_consent 标识符,延迟挂载防阻塞渲染,兼容 ITP 限制,并确保关闭按钮等效“拒绝”且键盘可达。

直接加一个带“接受/拒绝”按钮的固定底部横幅,同时用 document.cookie 控制显隐逻辑,就能满足基础合规要求;但真正难的是避免重复弹出、兼容 Safari 的 ITP 限制、以及不阻塞首屏渲染。
如何用原生 JS 实现无依赖的 Cookie 横幅显示逻辑
核心是读写 cookie_consent 这个标识符,而不是操作所有 Cookie。横幅只在用户未表态时显示,且首次访问必须默认隐藏(避免 FOUT)。
- 页面加载后立即检查
document.cookie是否包含cookie_consent=true - 若不存在,用
setTimeout(() => { showBanner() }, 100)延迟挂载横幅 DOM,防止干扰 LCP - 横幅元素需设
style="position: fixed; bottom: 0; left: 0; width: 100%; z-index: 9999;",不能用 CSS position sticky - 点击“接受”后写入:
document.cookie = "cookie_consent=true; path=/; max-age=31536000; SameSite=Lax"
为什么 Safari 和 iOS Chrome 经常不保存你的 Cookie 设置
因为 ITP(Intelligent Tracking Prevention)会拦截第三方上下文中的 document.cookie 写入,哪怕你只是在自己域名下操作 —— 只要页面有跨域资源(比如 Google Fonts、Analytics 脚本),就可能被降级为“分类上下文”,导致 max-age 被强制缩短到 7 天甚至 1 小时。
- 解决方案:去掉
domain属性,只保留path=/和SameSite=Lax - 验证是否写入成功:在控制台执行
document.cookie.includes("cookie_consent"),返回false就说明被拦截了 - 备用方案:当
document.cookie不可靠时,fallback 到localStorage.setItem("cookie_consent", "true"),并在检查逻辑中优先读 localStorage
点击“拒绝”后该禁用哪些脚本
“拒绝”不等于“禁用所有 Cookie”,而是停止非必要追踪行为。关键不是删脚本标签,而是阻止初始化调用。
立即学习“前端免费学习笔记(深入)”;
- Google Analytics:不要移除
gtag.js,但在加载后不执行gtag("config", "...") - Facebook Pixel:确保
fbq("init", "...")和fbq("track", "PageView")都被包裹在if (getConsent() === "true") { ... }中 - 自定义统计或热力图工具(如 Hotjar):检查其文档,找类似
hj("optout")或__hjOptions = { disabled: true }的禁用 API - 绝对不要在“拒绝”时清除已存在的 Cookie —— 这反而触发浏览器重置,可能引发二次提示
最易被忽略的一点:横幅的关闭按钮(×)必须等同于“拒绝”,不能只隐藏 DOM;否则用户刷新页面又看到,会误以为网站没记住选择。而且所有交互必须通过键盘 Enter 和 Space 键可达,否则 WCAG 2.1 AA 就不达标。



















