符合欧盟法规的Cookie同意弹窗内部代码如何实现
整个链路的核心合规原则是:未获得用户明确同意前,绝对不能加载/初始化Google Analytics、不能写入任何GA相关追踪Cookie,用户做出选择后按授权状态初始化GA,拒绝授权时开启全匿名模式不采集可识别个人身份的信息,所有授权状态存在本地必要Cookie中做持久化,避免重复弹窗。
核心运行逻辑拆解
- 页面首次加载时优先检查本地是否存在用户Cookie授权状态记录,无记录时弹出同意弹窗,此时GA相关代码完全不执行,不发起任何GA相关网络请求
- 用户点击「拒绝」:写入有效期6个月的授权状态标记Cookie,初始化GA时开启IP匿名化,关闭广告追踪、用户标识持久化能力,不存储任何非必要追踪Cookie
- 用户点击「允许」:写入有效期6个月的授权状态标记Cookie,按常规配置初始化GA,正常上报访问数据
- 用户后续访问时直接读取本地授权状态,按对应规则初始化GA,不再弹出弹窗;可在页脚预留Cookie设置入口,支持用户随时修改授权选择
- 授权状态Cookie到期后自动清除,重新向用户征求同意
具体代码实现
第一步:移除原有默认加载的GA全局代码
不要在页面head里提前写GA的初始化脚本,避免未授权就发起追踪请求。
第二步:实现基础工具函数与弹窗结构
// Cookie操作工具,用于读写授权状态 function setCookie(name, value, days) { const expires = new Date(); expires.setTime(expires.getTime() + days * 24 * 60 * 60 * 1000); document.cookie = `${name}=${value};expires=${expires.toUTCString()};path=/;SameSite=Lax`; } function getCookie(name) { const nameEQ = name + "="; const cookieArr = document.cookie.split(';'); for(let i=0;i < cookieArr.length;i++) { let c = cookieArr[i].trim(); if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length,c.length); } return null; } const CONSENT_COOKIE_NAME = "cookie_consent_status"; const CONSENT_EXPIRE_DAYS = 180; // 授权有效期6个月
<!-- Cookie同意弹窗 默认隐藏 --> <div id="cookie-consent-banner" style="display:none; position:fixed; bottom:0; left:0; right:0; background:#fff; padding:16px 24px; box-shadow:0 -2px 10px rgba(0,0,0,0.1); z-index:9999; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:12px;"> <p style="margin:0; font-size:14px; line-height:1.5;"> 本网站使用Cookie优化访问体验,您可以选择允许或拒绝非必要Cookie的使用,拒绝后我们将对访问数据做匿名化处理,不会影响网站正常浏览功能。 </p> <div style="display:flex; gap:12px;"> <button id="cookie-reject-btn" style="padding:8px 16px; border:1px solid #ccc; background:#f5f5f5; border-radius:4px; cursor:pointer;">拒绝非必要Cookie</button> <button id="cookie-accept-btn" style="padding:8px 16px; border:none; background:#1a73e8; color:#fff; border-radius:4px; cursor:pointer;">允许所有Cookie</button> </div> </div>
第三步:实现按授权状态初始化GA的核心逻辑
// 按授权状态初始化GA,基于GA官方Consent Mode v2标准 function initGA(consentStatus) { // 替换为你自己的GA4衡量ID const GA_MEASUREMENT_ID = 'G-XXXXXXXXXX'; // 动态加载GA脚本,未调用本函数时不会加载GA资源 const script = document.createElement('script'); script.async = true; script.src = `https://www.googletagmanager.com/gtag/js?id=${GA_MEASUREMENT_ID}`; document.head.appendChild(script); window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} // 按授权状态设置GA存储权限 gtag('consent', 'default', { 'ad_storage': consentStatus === 'accept' ? 'granted' : 'denied', 'analytics_storage': consentStatus === 'accept' ? 'granted' : 'denied', 'ad_user_data': consentStatus === 'accept' ? 'granted' : 'denied', 'ad_personalization': consentStatus === 'accept' ? 'granted' : 'denied' }); gtag('js', new Date()); gtag('config', GA_MEASUREMENT_ID, { anonymize_ip: true, // 强制开启IP匿名化 // 拒绝状态下禁用GA的Cookie存储能力 client_storage: consentStatus === 'accept' ? 'cookies' : 'none' }); } // 页面加载完成后执行判断逻辑 document.addEventListener('DOMContentLoaded', function() { const consentStatus = getCookie(CONSENT_COOKIE_NAME); const banner = document.getElementById('cookie-consent-banner'); const acceptBtn = document.getElementById('cookie-accept-btn'); const rejectBtn = document.getElementById('cookie-reject-btn'); // 已有授权记录直接初始化GA,不弹窗 if (consentStatus === 'accept' || consentStatus === 'reject') { initGA(consentStatus); return; } // 无授权记录显示弹窗 banner.style.display = 'flex'; // 同意按钮逻辑 acceptBtn.addEventListener('click', function() { setCookie(CONSENT_COOKIE_NAME, 'accept', CONSENT_EXPIRE_DAYS); banner.style.display = 'none'; initGA('accept'); }); // 拒绝按钮逻辑 rejectBtn.addEventListener('click', function() { setCookie(CONSENT_COOKIE_NAME, 'reject', CONSENT_EXPIRE_DAYS); banner.style.display = 'none'; initGA('reject'); }); })
合规注意事项
- 弹窗不能设置默认勾选同意,必须用户主动点击「允许」才视为有效同意;拒绝按钮不能做弱化样式(比如字体更小、置灰、放在难以点击的位置)
- 未获得用户同意前,不能发起任何GA相关的网络请求,监管核查时会直接检查页面加载初期的请求列表,提前加载GA脚本就算违规
- 若用户修改授权状态从「允许」切为「拒绝」,需要主动清除本地已存储的GA相关Cookie(
_ga、_gid、_ga_*开头的Cookie) - 仅存储授权状态的Cookie属于网站运行必要Cookie,不需要用户同意即可写入
- 以上实现完全符合欧盟ePrivacy条例和GDPR要求,中小站点不需要额外接入第三方付费同意管理平台即可使用
内容的提问来源于stack exchange,提问作者Proger
相关产品推荐
相关产品推荐

