原创 石小石Orz 2025-06-19 08:31 重庆
点击关注公众号,“技术干货”及时达!
石小石
,一个热爱技术分享的开源社区贡献者。写有《油猴脚本实战指南[1]》、《Vite 极速入门与进阶[2]》、《Threejs 极速入门》、《鸿蒙基础开发实践[3]》、《前端学 Java》等专栏。目前专注于微前端架构与 AI 相关技术的研究与工程实践。属性 / 方法
作用说明
示例代码
navigator.userAgent
获取浏览器的用户代理字符串,可以用于判断浏览器类型、系统类型
navigator.userAgent
navigator.platform
获取运行环境的操作系统平台类型(如 Win32、Linux x86_64、MacIntel)
navigator.platform
navigator.appVersion
获取浏览器版本信息和部分平台信息
navigator.appVersion
navigator.appName
获取浏览器名称(大多数现代浏览器返回 “Netscape”)
navigator.appName
navigator.language
返回当前浏览器的首选语言(如 “zh-CN”、“en-US”)
navigator.language
navigator.languages
返回用户的首选语言列表
navigator.languages
navigator.hardwareConcurrency
返回可用的逻辑处理器数量(CPU 核心数)
navigator.hardwareConcurrency
navigator.plugins
返回当前安装的插件列表(仅桌面浏览器有意义,且有兼容性限制)
navigator.plugins
navigator.onLine
判断当前浏览器是否联网
navigator.onLine
navigator.cookieEnabled
判断浏览器是否启用 Cookie
navigator.cookieEnabled
navigator.geolocation
提供地理位置定位服务(需要用户授权)
navigator.geolocation.getCurrentPosition(...)
navigator.maxTouchPoints
支持的最大触控点个数(触屏设备可用)
navigator.maxTouchPoints
navigator.mediaDevices
访问音视频设备管理 API(如获取麦克风、摄像头)
navigator.mediaDevices.getUserMedia(...)
navigator.clipboard
读写系统剪贴板(部分浏览器需要 https 环境和权限)
navigator.clipboard.writeText("Hello")
navigator.connection
获取网络连接信息对象(如带宽、类型,部分浏览器支持)
navigator.connection.effectiveType
navigator.userAgentData
在新标准中可用的一种用户代理信息对象,部分浏览器已支持,用户隐私性更高
navigator.userAgentData
偷个懒,让 「Tare」 直接帮我写个 Navigator 指纹示例吧。代码生成完毕,点击应用直接预览:经过测试,在同一个电脑上,这个指纹是稳定的,多次执行,这个值不会变。但这这个指纹明显有缺陷,我系统语言或者浏览器升级后,这个指纹肯定会改变。Canvas 指纹由于不同设备(包括操作系统、显卡、驱动、字体渲染引擎等)在绘制同一段 Canvas 内容时会存在细微差异,最终得到的图像数据(通常是像素或转成 base64)在不同设备上往往是不同的。这些细微差异生成的哈希值就是 “指纹”,由于只与设备性能有关,指纹稳定性显然比 Navigator 指纹高一些。<!DOCTYPE html><html><head> <title>Navigator 指纹示例</title></head><body> <h2>Navigator 指纹示例</h2> <pre id="output"></pre> <script> async function getNavigatorFingerprint() { // 收集 navigator 相关信息 const data = { userAgent: navigator.userAgent, platform: navigator.platform, language: navigator.language, languages: navigator.languages, cookieEnabled: navigator.cookieEnabled, hardwareConcurrency: navigator.hardwareConcurrency || 'N/A', deviceMemory: navigator.deviceMemory || 'N/A', webdriver: navigator.webdriver || false, }; // 将数据转成字符串 const dataString = JSON.stringify(data); // 计算 SHA-256 哈希 const hashBuffer = await crypto.subtle.digest( "SHA-256", new TextEncoder().encode(dataString) ); // 转成十六进制字符串 const hashArray = Array.from(new Uint8Array(hashBuffer)); const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); return { data, fingerprint: hashHex }; } getNavigatorFingerprint().then(result => { const output = document.getElementById('output'); output.textContent = "采集到的 Navigator 信息:\n" + JSON.stringify(result.data, null, 2) + "\n\n生成的指纹(SHA-256):\n" + result.fingerprint; }); </script></body></html>
生成的指纹还是很不错的。其他几种方式生成浏览器指纹都大同小异,这里就不介绍了。<!DOCTYPE html><html><head> <title>简单Canvas指纹示例</title></head><body> <h2>简单Canvas指纹示例</h2> <p>请打开控制台(F12)查看结果</p> <script> // 创建一个简单的Canvas指纹生成函数 function generateCanvasFingerprint() { // 创建canvas元素 const canvas = document.createElement('canvas'); canvas.width = 200; canvas.height = 100; // 获取绘图上下文 const ctx = canvas.getContext('2d'); // 填充背景 ctx.fillStyle = 'white'; ctx.fillRect(0, 0, canvas.width, canvas.height); // 绘制一些图形和文字 // 绘制红色矩形 ctx.fillStyle = 'red'; ctx.fillRect(20, 20, 50, 50); // 绘制蓝色圆形 ctx.fillStyle = 'blue'; ctx.beginPath(); ctx.arc(120, 45, 25, 0, Math.PI * 2); ctx.fill(); // 绘制文本 ctx.fillStyle = 'black'; ctx.font = '16px Arial'; ctx.fillText('Canvas指纹', 60, 80); // 获取canvas数据URL const dataURL = canvas.toDataURL(); // 简单哈希函数 function simpleHash(str) { let hash = 0; for (let i = 0; i < str.length; i++) { const char = str.charCodeAt(i); hash = ((hash << 5) - hash) + char; hash = hash & hash; // 转换为32位整数 } return hash.toString(16); // 转换为16进制 } // 计算指纹 const fingerprint = simpleHash(dataURL); return { fingerprint: fingerprint, dataURL: dataURL }; } // 生成并输出指纹 const result = generateCanvasFingerprint(); console.log('Canvas指纹:', result.fingerprint); console.log('Canvas数据URL前100个字符:', result.dataURL.substring(0, 100) + '...'); // 如果浏览器支持更安全的哈希算法,也可以使用它 if (window.crypto && window.crypto.subtle) { const encoder = new TextEncoder(); const data = encoder.encode(result.dataURL); window.crypto.subtle.digest('SHA-256', data) .then(hashBuffer => { // 将哈希缓冲区转换为十六进制字符串 const hashArray = Array.from(new Uint8Array(hashBuffer)); const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); console.log('Canvas指纹(SHA-256):', hashHex); }); } </script></body></html>