JS生成浏览器唯一标识解决方案

前端页面如何在浏览器中检测生成设备的唯一标识 一、前提:

  js本身是不能通过浏览器获取设备唯一标识的,但是可以获取其它的信息作为唯一标识,给用户一个 visitorId,并且根据这个 visitorId 记录一些用户的习惯。总之就是根据浏览器的一些特性生成的唯一标识。

二、业务场景:

  例如收藏或者关注功能,前端实现。

三、解决方案:FingerprintJS

  FingerprintJS 是一个浏览器指纹库,它查询浏览器属性(canvas、webgl、UserAgent、AudioContext等)并从中计算 hash 的访问者标识符。因为指纹哈希依赖于所有浏览器属性的精确匹配,使得它们在 > 2周的时间间隔内不稳定,所以自己要做下永久存储 localStorage,只有第一次存下用户Id就可以了。

 
java
复制代码
const options: Options = {
            excludes: {
                language: true,
                colorDepth: true,
                deviceMemory: true,
                pixelRatio: true,
                availableScreenResolution: true,
                timezoneOffset: true,
                timezone: true,
                sessionStorage: true,
                localStorage: true,
                indexedDb: true,
                addBehavior: true,
                openDatabase: true,
                cpuClass: true,
                doNotTrack: true,
                plugins: true,
                canvas: true,
                webglVendorAndRenderer: true,
                adBlock: true,
                hasLiedLanguages: true,
                hasLiedResolution: true,
                hasLiedOs: true,
                hasLiedBrowser: true,
                touchSupport: true,
                audio: true,
                enumerateDevices: true,
                hardwareConcurrency: true
            }
        };
        return new Promise((resolve) => {
            if (window.requestIdleCallback) {
                requestIdleCallback(function () {
                    Fingerprint2.get(options, function (components) {
                        const values = components.map(function (component) {
                            return component.value;
                        });
                        const murmur = Fingerprint2.x64hash128(values.join(''), 31);
                        resolve(murmur);
                    });
                })
            } else {
                setTimeout(function () {
                    Fingerprint2.get(options, function (components) {
                        const values = components.map(function (component) {
                            return component.value;
                        });
                        const murmur = Fingerprint2.x64hash128(values.join(''), 31);
                        resolve(murmur);
                    });
                }, 500)
            }
        })

另一种结局方案:会存在重复情况(同设备、内核、浏览器) 使用canvas生成指纹信息

 
java
复制代码
	static getFinger() {
 		const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        const txt = 'http://www.koal.com/';
        ctx.textBaseline = "top";
        ctx.font = "14px 'Arial'";
        ctx.textBaseline = "middle";
        ctx.fillStyle = "#f60";
        ctx.fillRect(125, 1, 62, 20);
        ctx.fillStyle = "#069";
        ctx.fillText(txt, 2, 15);
        ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
        ctx.fillText(txt, 4, 17);

        const b64 = canvas.toDataURL().replace("data:image/png;base64,", "");
        const bin = atob(b64);
        const crc = this.bin2hex(bin.slice(-16, -12));
        return crc;
    }

    static bin2hex(str) {
        var result = "";
        for (let i = 0; i < str.length; i++) {
            result += this.int16ToHex(str.charCodeAt(i));
        }
        return result;
    }

    static int16ToHex(i) {
        var result = i.toString(16);
        var j = 0;
        while (j + result.length < 4) {
            result = "0" + result;
            j++;
        }
        return result;
    }
posted @ 2024-02-22 15:14  CharyGao  阅读(1651)  评论(0编辑  收藏  举报