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

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

二、业务场景:

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

三、解决方案:FingerprintJS

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

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生成指纹信息

	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;
    }
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐