如何使用 JavaScript 检测用户是否启用三方 Cookie ?

今天继续来聊 CookieChrome 已经在 1.4 号开启了三方 Cookie1% 禁用灰度:

Chrome 三方 Cookie 禁用已正式开始!

不少小伙伴反馈已经命中了这个灰度,因为时间比较急,很多网站来不及改造,很多网站的正常功能在这个灰度策略下受到了影响。

在前面的文章中我们提到,对于一些还没来得及改造完的网站,Chrome 提供了一种便捷的方式来让命中灰度的用户手动关闭这个策略:

这个开关点击后可以允许指定域名继续使用三方 Cookie ,但是这个期限只有 90 天。

所以,如果大家的网站最近没有时间进行这些改造,大家可以在运行时来提示用户手动关闭三方 Cookie 的禁用策略。

那么问题来了,并不是所有用户都命中了这个策略,当前只有 1% ,我们可能给所有的用户都添加这个提示,所以我们如何在运行时检测用户是否命中了三方 Cookie 的灰度策略呢?

ini 复制代码
function checkCookie(){
    var cookieEnabled = navigator.cookieEnabled;
    if (!cookieEnabled){ 
        document.cookie = "testcookie"; 
        cookieEnabled = document.cookie.indexOf("testcookie")!=-1;
    }
    return cookieEnabled || showCookieFail();
}

function showCookieFail(){
  // do something here
}

checkCookie();

上面的代码片段可用于检查 Cookie 是否启用,但是对三方 Cookie 的检查就无能为力了,三方 Cookie 禁用的情况下还是会返回 true

我能想到的并且一直有效的方法就是添加一个外部(三方)的 iFrame,让它来检测 iFrame 内部是否可以访问到 Cookie,并且会将 Cookie 的可用状态通知给父应用。

虽然这听起来挺奇怪的,我们好像无法直接通过 iFrame 调用父页面的功能。但是我们可以使用 Message Event 来进行父子应用之间的通信,通过这个我们可以基于 URL 向其他浏览器发送消息,在我们现在这种情况下,我们可以从 iFrame 向可能在不同域上的父应用发送消息。

首先,我们在 iFrame 内添加一个立即执行函数。在这个函数中,我们添加一个消息事件监听器,这个监听器会在从父级应用程序调用时触发。当被调用时,它首先会验证请求,然后调用 checkCookiesEnable 函数来检查 Cookie 的状态并返回结果。然后,我们通过 parent.postMessage() 方法向父应用发送一条消息;在 iFrame 中,parent 是一个隐含的对象。

xml 复制代码
<!doctype html>
<html>
<head>
</head>
<body>
    <script>
        const checkCookiesEnable = () => {
            let isCookieEnabled = (window.navigator.cookieEnabled) ? true : false;
            if (typeof window.navigator.cookieEnabled == "undefined" && !isCookieEnabled) {
                // 尝试设置一个测试cookie
                document.cookie = "testcookie";
                // 检查cookie是否已设置
                isCookieEnabled = (document.cookie.indexOf("testcookie") != -1) ? true : false;
            }

            return isCookieEnabled;
        }

        // 监听消息事件,响应从父窗口传来的消息
        (function () {
            window.addEventListener('message', event => {
                try {
                    let data = JSON.parse(event.data)
                    if (data['test'] !== 'cookie')
                        return
                    let result = checkCookiesEnable();
                    // 将结果通过消息事件发送到父窗口
                    parent.postMessage(JSON.stringify({
                        'result': result
                    }), event.origin);
                }
                catch (e) {
                    console.error(e)
                }
            });
        })();
    </script>
</body>
</html>

在这里,我们将添加一个消息事件处理程序,然后在插入任何第三方脚本之前插入我们的 iFrame。一旦 iFrame 加载完毕,我们将通过 frame.contentWindow 对象向我们的 iFrame 发送 postMessage,使用 "*" 允许 postMessage 任何来源(不同的域)。

然后,iFrame 内部的函数检查iFrameCookie 状态并发送一个消息,该消息被我们的 messagehandler 拦截。检查消息是否由 iFrame 发送,事件现在将保存来自 iFrame 内的 checkCookieEnable 函数结果的响应。

下面是一个示例函数,它接受iframeUri和一个回调函数,在收到结果后将被调用。

ini 复制代码
const cookieTest = (iFrameUri, callBack) => {
    let messageHandler = (event) => {
        // 在这里检查受信任的来源
        const data = JSON.parse(event.data);
        callBack(data['result']);
        window.removeEventListener('message', messageHandler);
        document.body.removeChild(frame);
    };

    // 监听消息事件,响应从 iframe 窗口传来的消息
    window.addEventListener('message', messageHandler);

    // 创建并添加一个隐藏的 iframe 元素
    const frame = document.createElement('iframe');
    frame.src = iFrameUri;
    frame.sandbox = "allow-scripts allow-same-origin";
    frame.style = `display:none`;
    frame.onload = (e) => {
        // 向 iframe 发送一个消息,请求检查 cookie 的情况
        frame.contentWindow.postMessage(JSON.stringify({ 'test': 'cookie' }), '*');
    };

    document.body.appendChild(frame);
};

export default cookieTest;

你可以直接把上面的代码片段放入你的网站中,并提供一个回调函数来为用户呈现适当的消息。

现在,我们可以成功地在运行时检测到用户的第三方 Cookie 是否已启用了!

相关推荐
毕设十刻23 分钟前
基于Vue的鲜花销售系统33n62(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
IT_陈寒29 分钟前
Spring Boot 3.2震撼发布:5个必知的新特性让你开发效率提升50%
前端·人工智能·后端
初遇你时动了情35 分钟前
前端使用TensorFlow.js reactjs调用本地模型 实现图像、文本、音频/声音、视频相关识别
前端·javascript·tensorflow
广州华水科技41 分钟前
单北斗GNSS变形监测系统安装与应用解析,提升位移监测精度
前端
J***Q29244 分钟前
前端微前端框架原理,qiankun源码分析
前端·前端框架
菜鸟‍44 分钟前
【前端学习】React学习【万字总结】
前端·学习·react.js
百***84451 小时前
Webpack、Vite区别知多少?
前端·webpack·node.js
Mintopia1 小时前
零信任架构下的 WebAIGC 服务安全技术升级方向
前端·人工智能·trae
敏姐的后花园3 小时前
模考倒计时网页版
java·服务器·前端
AiXed4 小时前
PC微信WDA算法
前端·javascript·macos