十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Front-End Checklist Cookie Consent 规则:GDPR 合规的 Cookie 同意机制从审查到实现

Front-End Checklist Cookie Consent 规则:GDPR 合规的 Cookie 同意机制从审查到实现 Front-End Checklist Cookie Consent 规则GDPR 合规的 Cookie 同意机制从审查到实现【免费下载链接】Front-End-Checklist The essential checklist for modern web development, for humans and AI agents项目地址: https://gitcode.com/gh_mirrors/fr/Front-End-Checklist本文基于 Front-End Checklist 仓库中的cookie-consent技能文档skills/cookie-consent/SKILL.md及其完整规则正文skills/cookie-consent/references/rule.md系统讲解“展示 Cookie 同意提示”这一隐私审查规则它要求网站在放置非必要 Cookie分析、广告、个性化之前必须先获得用户知情同意。读完后你将掌握 Cookie 分类与同意要求、符合 GDPR 的手动实现代码TypeScript 同意存储 React 同意横幅 Google Consent Mode v2以及一套可执行的验证清单能够对真实站点或代码库进行合规审查并落地修复。一、这条规则在仓库中的定位cookie-consent是 Front-End Checklist 面向“人类与 AI Agent”的规则语料中的一条privacy类别规则其元数据在 SKILL.md 的 frontmatter 中声明category: privacy、priority: high、difficulty: intermediate、estimatedTime: 30分钟aiContext说明了适用场景审查网站 GDPR/CCPA 合规性时确认是否在设置非必要 Cookie 之前获得了同意。该技能文件是由规则源文件 packages/content/rules/en/privacy/cookie-consent.mdx 自动生成而来。生成脚本 scripts/generate/generate-skills.ts 会把每条规则 MDX 转换为skills/{slug}/SKILL.mdfrontmatter check/fix/explain/codeReview 提示词与references/rule.mdMDX 正文剥离 JSX 后的纯 Markdown两个产物仓库通过pnpm generate:skills重新生成。因此本文所讲的每一条内容都能在 MDX 源规则中找到对应依据两处表述一致。技能可被 Agent 直接安装使用见 README.md 与生成脚本头部注释npx skills add frontendchecklist/skills npx skills add frontendchecklist/skills --skill cookie-consent二、合规背景与风险为什么这条规则优先级为 highGDPR 违规最高可处以2000 万欧元或全球年营业额 4%取较高者的罚款欧盟各监管机构已实际对“未经有效同意部署追踪 Cookie”的组织开出罚单。这一风险说明同时出现在 SKILL.md 与 references/rule.md 的 “Why It Matters” 部分也是规则 frontmatter 中priority: high的依据。适用范围不止于欧盟。规则原文指出欧盟GDPR与ePrivacy 指令要求网站在放置非必要 Cookie 前获得知情同意类似要求存在于CCPA美国加州、LGPD巴西、PIPEDA加拿大、PECR英国。规则引用的权威标准见 cookie-consent.mdx 的sources元数据包括 GDPR Article 6处理的合法性、GDPR Recital 32同意以及 ICO 的 PECR Cookie 指南——在判定规则“已满足”之前实现必须对照这些条款逐项核对。三、Cookie 分类哪些需要同意哪些不需要规则给出的快速参考Quick Reference要点全部继承自 references/rule.mdGDPR 要求在设置非必要 Cookie分析、广告、个性化之前获得同意必要/严格必需 Cookie会话、安全、登录不需要同意同意必须是自由给予freely given、具体specific、知情informed、无歧义unambiguous的——预勾选框无效用户必须能够像给出同意一样容易地撤回同意脚本与像素pixel必须在用户主动接受对应类别之前不得加载非必要追踪器在“同意前”和“撤回后”都必须保持阻断。完整的 Cookie 分类表如下类别示例是否需要同意Strictly necessary严格必需会话 Cookie、CSRF Token、登录状态否Functional功能性语言偏好、无障碍设置视情况——若为服务核心则视为必需Analytics分析类Google Analytics、Mixpanel是Advertising广告类Google Ads、Facebook Pixel、再营销是Social media社交媒体Twitter/LinkedIn 分享按钮、嵌入内容是注意“功能性”这一灰色地带语言偏好、无障碍开关等如果它们构成服务本身的核心例如多语言站点切换语言是服务前提可能被视为严格必需而豁免但规则建议从保守侧判定能分类到“需同意”的就不放进“必需”。四、什么才算有效同意规则依据 GDPR 第 4(11) 条对“同意”的定义给出四项硬性要求自由给予Freely given——拒绝必须和接受一样容易不允许用 cookie wall不同意就封锁访问逼迫用户具体Specific——不同目的必须分开授权分析类与广告类是两个独立的同意项不能一揽子打包知情Informed——用户必须清楚自己在为什么授权无歧义Unambiguous——需要一个明确的肯定性动作预勾选的复选框不构成有效同意。此外用户必须能在之后随时重新审视并修改选择入口应当稳定例如页脚链接、账户设置或隐私中心。这一点与 SKILL.md Code Review 提示词中“横幅消失后仍存在持久的『修改 Cookie 设置』路径”相互印证。五、审查清单Check 与 Code Review 怎么做规则提供了四组面向 Agent 的提示词Check / Fix / Explain / Code Review审查动作上重点关注三件事Check检查——见 SKILL.md站点是否在设置非必要 Cookie 之前展示了 Cookie 同意提示分析、广告、追踪脚本是否确实等到用户主动接受后才加载用户拒绝非必要 Cookie 后是否仍能正常访问内容无 cookie wall。Code Review代码审查——审查范围覆盖服务端配置、响应头、表单及相关集成点重点核对标记出违反规则的具体响应、Cookie 或浏览器行为并对照类生产环境而非本地的实际响应验证追踪器的初始化是否被同意状态“门控”gated on consent横幅关闭之后是否仍存在可见的“修改 Cookie 设置”持久入口。Explain解释——向非技术干系人说明 GDPR 对 Cookie 同意的要求、必要与非必要 Cookie 的区别、预勾选框为何无效以及技术上的合规实现长什么样。六、FixCMP 方案与手动实现规则给出的修复方向有三层实现一个在获得同意前阻断非必要脚本的 CMPConsent Management Platform把分析与追踪标签配置为仅在明确同意后初始化提供用户随时修改同意偏好的机制。6.1 使用现成 CMP规则推荐的合规 CMP 包括Cookiebot— 自动 Cookie 扫描 同意管理OneTrust— 企业级合规CookieYes— 面向中小站点Osano— 对开源友好。6.2 手动实现同意必须先于脚本加载最典型的违规形态是把分析脚本直接写在 HTML 头部、无条件加载。规则给出的正确/错误对照!-- Do NOT load analytics before consent -- !-- ❌ Wrong: loads before consent -- script async srchttps://www.googletagmanager.com/gtag/js?idG-XXXXX/script !-- ✅ Correct: analytics loaded only after consent -- script // Check consent before loading analytics if (getConsentStatus(analytics) granted) { loadGoogleAnalytics() } /script /code6.3 同意存储与版本失效consent.ts 完整实现下面是规则中的 TypeScript 实现以 MDX 源文件 cookie-consent.mdx 中的完整版为准其中CONSENT_VERSION是关键细节——当同意目的发生变化时必须升级版本号旧版本的存量同意即被自动作废用户需要重新被征询同意// consent.ts const CONSENT_KEY cookie-consent const CONSENT_VERSION v2 // Bump when purposes change interface ConsentPreferences { version: string analytics: boolean advertising: boolean functional: boolean timestamp: number } export function getConsent(): ConsentPreferences | null { try { const stored localStorage.getItem(CONSENT_KEY) if (!stored) return null const parsed JSON.parse(stored) as ConsentPreferences // Invalidate old consent versions if (parsed.version ! CONSENT_VERSION) return null return parsed } catch { return null } } export function setConsent(preferences: OmitConsentPreferences, version | timestamp) { const consent: ConsentPreferences { ...preferences, version: CONSENT_VERSION, timestamp: Date.now(), } localStorage.setItem(CONSENT_KEY, JSON.stringify(consent)) applyConsentDecision(consent) } function applyConsentDecision(consent: ConsentPreferences) { if (consent.analytics) { loadGoogleAnalytics() } else { disableAnalyticsCookies() } if (consent.advertising) { loadAdvertisingPixels() } else { disableAdvertisingCookies() } } function loadGoogleAnalytics() { const script document.createElement(script) script.src https://www.googletagmanager.com/gtag/js?idG-XXXXX script.async true document.head.appendChild(script) }从源码结构看这里的设计要点值得注意拒绝即落盘setConsent对“拒绝”同样写入 localStorage。这样下次访问时getConsent()返回非空横幅不再重复弹出——拒绝本身也是一种需要持久化的决定且保证“撤回后追踪器保持阻断”这一要求Quick Reference 第 6 条成立读取即校验版本parsed.version ! CONSENT_VERSION时返回null等价于把旧同意视为“从未同意”触发重新征询决策集中应用applyConsentDecision是唯一的副作用入口每个类别都有load*与disable*两条路径保证同意变更包括撤回能即时反映到脚本状态。6.4 React 同意横幅组件规则给出的 React客户端组件实现要点仅在getConsent()为空时显示横幅“拒绝非必要”“管理偏好”“接受全部”三条路径对称提供体现“拒绝与接受同样容易”“严格必需”复选框checked disabled readOnly只展示不可取消因为该类别豁免同意整个横幅使用roledialog、aria-modaltrue、aria-labelledby保证可访问性use client import { useState, useEffect } from react import { getConsent, setConsent } from ./consent export function CookieConsentBanner() { const [visible, setVisible] useState(false) const [showDetails, setShowDetails] useState(false) const [analytics, setAnalytics] useState(false) const [advertising, setAdvertising] useState(false) useEffect(() { // Show banner only if no consent has been recorded if (!getConsent()) { setVisible(true) } }, []) const acceptAll () { setConsent({ analytics: true, advertising: true, functional: true }) setVisible(false) } const rejectAll () { setConsent({ analytics: false, advertising: false, functional: false }) setVisible(false) } const savePreferences () { setConsent({ analytics, advertising, functional: true }) setVisible(false) } if (!visible) return null return ( div roledialog aria-modaltrue aria-labelledbyconsent-title classNamecookie-consent-banner h2 idconsent-titleWe use cookies/h2 p We use cookies to improve your experience. Some are essential; others help us understand how you use our site.{ } a href/privacyPrivacy Policy/a /p {showDetails ( div classNameconsent-details label input typecheckbox checked disabled readOnly / strongStrictly necessary/strong — required for the site to work /label label input typecheckbox checked{analytics} onChange{(e) setAnalytics(e.target.checked)} / strongAnalytics/strong — helps us understand usage patterns /label label input typecheckbox checked{advertising} onChange{(e) setAdvertising(e.target.checked)} / strongAdvertising/strong — personalised ads /label /div )} div classNameconsent-actions button onClick{rejectAll}Reject non-essential/button button onClick{() setShowDetails(!showDetails)} {showDetails ? Hide : Manage preferences} /button {showDetails ( button onClick{savePreferences}Save preferences/button )} button onClick{acceptAll} classNameprimary Accept all /button /div /div ) }一个值得对照实现的细节savePreferences中functional: true是硬编码的——因为本例把“功能性”视为站点运转所需与分类表中“Functional若为服务核心则视为必需”的判定一致。如果你的场景里语言偏好不属于服务核心应改为独立的偏好开关。6.5 Google Consent Mode v2如果站点使用 Google Analytics 或 Google Ads还需要通过 Consent Mode 向 Google 上报同意状态。初始化必须在加载 GTM 或 gtag.js之前完成默认状态一律denied// Initialize consent mode BEFORE loading GTM or GA window.dataLayer window.dataLayer || [] function gtag() { dataLayer.push(arguments) } // Set default state — deny all until consent is given gtag(consent, default, { analytics_storage: denied, ad_storage: denied, ad_user_data: denied, ad_personalization: denied, wait_for_update: 500, // milliseconds to wait for consent update })用户在 CMP 中做出选择后再调用update同步真实状态// After user grants consent gtag(consent, update, { analytics_storage: userConsent.analytics ? granted : denied, ad_storage: userConsent.advertising ? granted : denied, })wait_for_update: 500表示 gtag 在初始化后等待 500ms给同步脚本例如从 localStorage 恢复已存同意并调用update一个时间窗口。仓库中另有一条专门的性能类规则 packages/content/rules/en/performance/consent-mode.mdx补充了update的完整字段写法ad_user_data、ad_personalization也一并置为granted与数据建模等要点可与本规则配合使用。七、最常见的反模式与验证清单最典型的反模式规则中的 Warning 原文强调许多站点弹出了 Cookie 横幅但页面里无论用户怎么选分析与广告脚本照样加载——这不构成 GDPR 合规。横幅只是“告知”脚本执行才是“行为”脚本必须在用户主动接受对应类别之后才允许执行。验证Verification分两部分自动化检查在类生产环境而非本地开发中测试受影响流程任何有意为之的例外都要显式记录在案。手动检查检查最终 HTTP 响应或浏览器行为确认控制确实被执行而不只是横幅存在确认第三方集成与嵌入在限制生效之后仍然正常工作先接受分析类 Cookie再撤回确认下一次页面加载时追踪器不再初始化确认横幅消失后仍然可见“Cookie settings”或等价控制入口。这套验证方法也可以直接用作 CI 或 E2E 断言的设计输入拒绝态下断言document.querySelectorAll(script[src*googletagmanager.com])为空、撤回后刷新页面再次断言、以及 DOM 中断言“Cookie settings”链接可见。八、在整套检查清单中的位置cookie-consent并不是孤立的一条规则。在 packages/content/checklists/en/privacy-and-consent.mdxPrivacy Consent 检查清单中它与数据最小化、隐私政策、被遗忘权、第三方 Cookie、Consent Mode、HTTPS、Referrer-Policy、CSP 等规则组成一次约 35 分钟的隐私专项审查该清单的审查提示也强调要“在给出同意之前和之后分别测试站点”“检查网络请求与存储键而不只是横幅 UI”“把第三方脚本纳入隐私审查范围而不是例外”。规则 frontmatter 中还声明了四条关联规则审查时可一并覆盖third-party-cookies——同属 privacy 领域常与 Cookie 同意一起审查privacy-policy——隐私政策文案必须与前端实际行为一致interstitials插入层与 import-on-interaction交互时再加载——在真实审计中频繁与本规则交叉共同影响同一批实现决策。九、小结cookie-consent这条规则的核心可以压缩成三句话同意必须先于行为脚本不得先于同意加载、同意必须可撤回且入口持久横幅之后仍有“修改设置”、拒绝必须与接受等价无 cookie wall、无预勾选。仓库通过“MDX 源规则 → 自动生成的 SKILL.md references/rule.md → Agent 可安装技能”这条管线把这套隐私审查标准变成了人和 AI 都能直接执行的检查项而 references/rule.md 中的consent.ts版本控制、applyConsentDecision双侧决策与 Consent Mode v2 三段式配置则给出了从零落地一套合规同意机制的完整代码骨架。【免费下载链接】Front-End-Checklist The essential checklist for modern web development, for humans and AI agents项目地址: https://gitcode.com/gh_mirrors/fr/Front-End-Checklist创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表