Angular 18集成Google Maps与ReCaptcha如何符合GDPR Cookie合规?
欧盟Cookie法规核心要求:非必要第三方Cookie(如Google Maps、ReCaptcha产生的跟踪/功能Cookie)必须获得用户明确同意后才能加载。以下是针对Angular18的落地实现方案:
1. 实现Cookie同意管理组件
先做一个基础的同意弹窗,支持用户选择是否允许第三方服务的Cookie,将选择结果持久化到localStorage。
组件模板(cookie-consent.component.html)
<div class="cookie-consent-overlay" *ngIf="showConsent"> <div class="consent-modal"> <h3>Cookie 设置</h3> <p>我们使用必要Cookie保障网站运行,第三方服务(Google Maps、ReCaptcha)需要您的同意才能加载对应的Cookie。</p> <div class="consent-options"> <label><input type="checkbox" [(ngModel)]="acceptNecessary" disabled> 必要Cookie</label> <label><input type="checkbox" [(ngModel)]="acceptThirdParty"> 第三方服务Cookie(Maps/ReCaptcha)</label> </div> <div class="consent-actions"> <button (click)="saveConsent()">保存设置</button> <button (click)="acceptAll()">全部同意</button> </div> </div> </div>
组件逻辑(cookie-consent.component.ts)
import { Component, OnInit } from '@angular/core'; import { FormsModule } from '@angular/forms'; @Component({ selector: 'app-cookie-consent', standalone: true, imports: [FormsModule], templateUrl: './cookie-consent.component.html', styleUrls: ['./cookie-consent.component.css'] }) export class CookieConsentComponent implements OnInit { showConsent = false; acceptNecessary = true; acceptThirdParty = false; ngOnInit(): void { // 检查是否已有同意记录 const consent = localStorage.getItem('cookieConsent'); if (!consent) { this.showConsent = true; } } saveConsent(): void { localStorage.setItem('cookieConsent', JSON.stringify({ necessary: this.acceptNecessary, thirdParty: this.acceptThirdParty })); this.showConsent = false; // 触发同意变更事件,通知其他组件加载第三方服务 window.dispatchEvent(new CustomEvent('cookieConsentUpdated')); } acceptAll(): void { this.acceptThirdParty = true; this.saveConsent(); } }
2. 动态加载Google Maps组件
不要在应用启动时直接导入Google Maps的依赖,而是等待用户同意后再动态加载脚本并初始化地图。
地图组件逻辑(google-maps.component.ts)
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core'; @Component({ selector: 'app-google-maps', standalone: true, template: '<div #mapContainer style="width: 100%; height: 400px;"></div>' }) export class GoogleMapsComponent implements OnInit { @ViewChild('mapContainer') mapContainer!: ElementRef<HTMLDivElement>; private map: google.maps.Map | undefined; ngOnInit(): void { // 监听同意变更事件 window.addEventListener('cookieConsentUpdated', () => this.loadMap()); // 页面加载时检查已有同意 const consent = JSON.parse(localStorage.getItem('cookieConsent') || '{}'); if (consent.thirdParty) { this.loadMap(); } } private loadMap(): void { // 检查脚本是否已加载 if (document.querySelector('script[src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"]')) { this.initMap(); return; } // 动态加载Google Maps脚本 const script = document.createElement('script'); script.src = 'https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY'; script.onload = () => this.initMap(); document.body.appendChild(script); } private initMap(): void { this.map = new google.maps.Map(this.mapContainer.nativeElement, { center: { lat: -34.397, lng: 150.644 }, zoom: 8 }); } }
3. 控制Google ReCaptcha加载
同理,ReCaptcha脚本仅在用户同意后加载,可通过条件渲染+动态脚本注入实现。
ReCaptcha组件逻辑(recaptcha.component.ts)
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core'; @Component({ selector: 'app-recaptcha', standalone: true, template: '<div #recaptchaContainer></div>' }) export class RecaptchaComponent implements OnInit { @ViewChild('recaptchaContainer') recaptchaContainer!: ElementRef<HTMLDivElement>; ngOnInit(): void { window.addEventListener('cookieConsentUpdated', () => this.loadRecaptcha()); const consent = JSON.parse(localStorage.getItem('cookieConsent') || '{}'); if (consent.thirdParty) { this.loadRecaptcha(); } } private loadRecaptcha(): void { if (document.querySelector('script[src="https://www.google.com/recaptcha/api.js"]')) { this.renderRecaptcha(); return; } const script = document.createElement('script'); script.src = 'https://www.google.com/recaptcha/api.js'; script.onload = () => this.renderRecaptcha(); document.body.appendChild(script); } private renderRecaptcha(): void { grecaptcha.render(this.recaptchaContainer.nativeElement, { sitekey: 'YOUR_RECAPTCHA_SITE_KEY', callback: (response: string) => { // 处理验证回调 } }); } }
4. 合规补充措施
- Cookie政策页面:明确列出Google Maps(如
NID、SID)和ReCaptcha(如__Secure-1PAPISID、__Secure-1PSID)的Cookie类型、用途、有效期,以及用户修改同意设置的方法。 - 全局同意检查:在
app.component.ts中初始化时检查同意状态,若用户未同意,默认不加载任何第三方服务。 - 静态地图 fallback:用户未同意前,显示Google静态地图图片(无需Cookie),点击后提示需要同意才能加载交互地图。
内容的提问来源于stack exchange,提问作者Mario Proietti
相关产品推荐
相关产品推荐

