vh-plugin
Version:
轻量级JS插件包
59 lines (54 loc) • 2.73 kB
text/typescript
/**
* @description: 取用户唯一标识
*/
import $MD5 from "../utils/md5";
const getvhHash = (v: string) => v.split("").reduce((hash, char) => (hash << 5) + hash + char.charCodeAt(0), 5666) >>> 0;
const OneKey = (safe?: boolean) => {
const userAgent: string = safe ? navigator.userAgent || "userAgent" : "";
const screenWidth: number = safe ? screen.width || 0 : 0;
const screenHeight: number = safe ? screen.height || 0 : 0;
const colorDepth: number = screen.colorDepth || 0;
const timezoneOffset: number = new Date().getTimezoneOffset() || 0;
const timeZone: string = Intl.DateTimeFormat().resolvedOptions().timeZone || "timeZone";
const hardwareConcurrency: number = navigator.hardwareConcurrency || 0;
const language: string = navigator.language || "language";
const languages: string[] = [...(navigator.languages || ["languages"])];
const onLine: string | boolean = navigator.onLine || "onLine";
const cookieEnabled: string | boolean = navigator.cookieEnabled || "cookieEnabled";
const doNotTrack: string = navigator.doNotTrack || "doNotTrack";
// 唯一Canvas元素
const getvhCanvasHash = () => {
const canvas: any = document.createElement("canvas");
const ctx: any = canvas.getContext("2d");
const en: string = "www.vvhan.com";
const zh: string = "骤雨重山博客";
ctx.textBaseline = "top";
ctx.font = "14px 'Arial'";
ctx.textBaseline = "alphabetic";
ctx.fillStyle = "#f60";
ctx.fillRect(125, 1, 62, 20);
ctx.fillStyle = "#069";
ctx.fillText(`${en} - ${zh}`, 2, 15);
ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
ctx.fillText(`${en} - ${zh}`, 4, 17);
return getvhHash(canvas.toDataURL());
};
// 默认字体
const getvhFonts = () => {
const fontList = ["Arial", "Verdana", "Times New Roman", "Courier New", "Georgia", "Comic Sans MS", "Trebuchet MS", "Arial Black", "Impact", "San Francisco", "Lucida Grande", "Segoe UI", "Roboto"];
const canvas = document.createElement("canvas");
const context: any = canvas.getContext("2d");
const text = "abcdefghijklmnopqrstuvwxyz0123456789";
const availableFonts = fontList
.map((font: string) => {
context.font = `16px ${font}`;
const width = context.measureText(text).width;
context.font = `16px 'HelloHan'`;
return context.measureText(text).width !== width ? font : null;
})
.filter(Boolean);
return availableFonts.join(",");
};
return $MD5(JSON.stringify({ userAgent, screenWidth, screenHeight, colorDepth, timezoneOffset, timeZone, language, languages, hardwareConcurrency, onLine, cookieEnabled, doNotTrack, fonts: getvhFonts(), canvasHash: getvhCanvasHash() })).toString();
};
export { OneKey };