如何实现检测访客30天内是否访问过example.com并触发dataLayer事件?
之前尝试iframe和直接读取Cookie失败的核心原因是浏览器同源策略:前端脚本无法直接读取其他域名下的Cookie或LocalStorage,必须通过服务器端配合或跨域消息传递来实现。以下是两种经过验证的方案:
方案1:第一方Cookie + 服务器端像素接口
这种方案依赖服务器端验证Cookie,绕过前端跨域限制,兼容性最好。
步骤1:在example.com设置跨域可用的Cookie
在你的网站(example.com)的任意页面添加以下脚本,设置有效期30天的Cookie,确保跨域场景下能被服务器读取:
// 在example.com页面加载时执行 document.cookie = "visited_example=true; max-age=2592000; path=/; domain=example.com; SameSite=None; Secure";
注意:
SameSite=None; Secure是跨域Cookie生效的必要条件,你的网站必须是HTTPS协议。
步骤2:部署服务器端验证接口
在example.com服务器上创建一个接口文件(比如check-visit.php),用于检查访客的Cookie并返回触发dataLayer的脚本:
<?php // 设置响应类型为JS header('Content-Type: application/javascript'); // 限制允许的域名(推荐替换为客户的具体域名,比如https://client-site.com) $allowedOrigins = ['https://client-site.com', 'https://another-client.com']; $origin = $_SERVER['HTTP_ORIGIN'] ?? ''; if (in_array($origin, $allowedOrigins)) { header("Access-Control-Allow-Origin: $origin"); } // 检查Cookie是否存在且有效 $hasVisited = isset($_COOKIE['visited_example']) && $_COOKIE['visited_example'] === 'true'; if ($hasVisited) { // 返回触发dataLayer的代码 echo "window.dataLayer = window.dataLayer || []; dataLayer.push({'event': 'visited_example_com'});"; } ?>
步骤3:客户网站嵌入接口脚本
让客户在他们的网站中添加以下脚本标签,加载你的验证接口:
<script src="https://example.com/check-visit.php" async></script>
当访客曾访问过example.com时,接口会返回触发dataLayer事件的代码,自动执行。
方案2:LocalStorage + 跨域消息传递(PostMessage)
这种方案不需要服务器端开发,依赖iframe和PostMessage实现跨域通信,适合无法部署服务器接口的场景。
步骤1:在example.com记录访问时间
在你的网站(example.com)添加脚本,用LocalStorage记录访客的访问时间(同时保留Cookie作为兼容 fallback):
// 在example.com页面加载时执行 localStorage.setItem('example_visit_date', Date.now().toString()); // 同时设置Cookie作为兼容 document.cookie = "visited_example=true; max-age=2592000; path=/; domain=example.com; SameSite=None; Secure";
步骤2:创建跨域检查页面
在example.com创建一个专门的检查页面(比如cross-domain-check.html),用于向客户网站发送验证结果:
<!DOCTYPE html> <html> <body> <script> function hasVisitedIn30Days() { // 检查LocalStorage const visitDate = localStorage.getItem('example_visit_date'); if (visitDate) { const thirtyDaysAgo = Date.now() - 2592000000; // 30天对应的毫秒数 return parseInt(visitDate) > thirtyDaysAgo; } // 检查Cookie作为 fallback const cookieMatch = document.cookie.match(/visited_example=true/); return cookieMatch !== null; } // 页面加载完成后向父页面发送消息 window.addEventListener('load', () => { const result = hasVisitedIn30Days(); if (window.parent && result) { // 最好替换为客户的具体域名,比如'https://client-site.com',提升安全性 window.parent.postMessage({ type: 'EXAMPLE_VISIT_VERIFIED', hasVisited: true }, '*'); } }); </script> </body> </html>
步骤3:客户网站嵌入iframe并监听消息
让客户在他们的网站中添加以下代码,嵌入隐藏iframe并监听来自example.com的消息:
<iframe src="https://example.com/cross-domain-check.html" style="display: none;" id="example-visit-check"></iframe> <script> window.addEventListener('message', (event) => { // 严格验证消息来源,防止恶意伪造 if (event.origin !== 'https://example.com') return; if (event.data.type === 'EXAMPLE_VISIT_VERIFIED' && event.data.hasVisited) { window.dataLayer = window.dataLayer || []; dataLayer.push({'event': 'visited_example_com'}); } }); </script>
关键注意事项
- HTTPS要求:两种方案都需要example.com是HTTPS协议,否则现代浏览器会阻止跨域Cookie和PostMessage的正常工作。
- 安全性优化:不要在服务器端接口或PostMessage中使用
*作为允许的Origin,务必指定客户的具体域名,避免被恶意网站滥用。 - 兼容性:方案1的兼容性更好,支持所有现代浏览器及旧版浏览器;方案2需要浏览器支持LocalStorage和PostMessage(IE8+支持)。
内容的提问来源于stack exchange,提问作者Paweł Gniadkowski

