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;
}
摘抄自网络,便于检索查找。