VUE项目中使用fingerprintjs获取客户端指纹

在 Vue3 项目中生成客户端指纹(用于唯一标识客户端设备 / 浏览器),下面提供两种可行方案,其中第三方成熟库方案优先推荐(高效、稳定、兼容性好),同时补充手动实现方案(轻量、可定制)。

一、优先方案:使用第三方库 fingerprintjs(推荐)

fingerprintjs 是目前最主流的客户端指纹生成库,v4 版本专门针对现代浏览器优化,支持 Vue3,生成的指纹唯一性高、稳定性强,还能规避很多手动实现的坑。

步骤 1:安装依赖

bash
 
运行
 
# npm
npm install @fingerprintjs/fingerprintjs --save

# yarn
yarn add @fingerprintjs/fingerprintjs

# pnpm
pnpm add @fingerprintjs/fingerprintjs
 

步骤 2:在 Vue3 中使用(两种组件写法均支持)

场景 1:组合式 API(<script setup>

vue
 
<template>
  <div>客户端指纹:{{ clientFingerprint }}</div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import FingerprintJS from '@fingerprintjs/fingerprintjs'

const clientFingerprint = ref('')

// 注意:需在组件挂载后执行(确保浏览器环境可用)
onMounted(async () => {
  // 1. 初始化指纹库
  const fp = await FingerprintJS.load()

  // 2. 获取客户端指纹(核心步骤)
  const result = await fp.get()

  // 3. 保存指纹(result.visitorId 即为唯一客户端标识)
  clientFingerprint.value = result.visitorId
  
  // 可选:查看更多客户端信息(如浏览器、设备等)
  console.log('客户端详细信息:', result.components)
})
</script>
 

场景 2:选项式 API

vue
 
<template>
  <div>客户端指纹:{{ clientFingerprint }}</div>
</template>

<script>
import FingerprintJS from '@fingerprintjs/fingerprintjs'

export default {
  data() {
    return {
      clientFingerprint: ''
    }
  },
  async mounted() {
    // 初始化并获取指纹
    const fp = await FingerprintJS.load()
    const result = await fp.get()
    this.clientFingerprint = result.visitorId
  }
}
</script>
 

场景 3:全局复用(封装为工具函数)

如果多个组件需要使用,可封装为全局工具函数(src/utils/fingerprint.js):
 
javascript
 
运行
 
// src/utils/fingerprint.js
import FingerprintJS from '@fingerprintjs/fingerprintjs'

// 封装为Promise函数,方便全局调用
export const getClientFingerprint = async () => {
  try {
    const fp = await FingerprintJS.load()
    const result = await fp.get()
    return result.visitorId
  } catch (error) {
    console.error('生成客户端指纹失败:', error)
    return null
  }
}
 
 
在组件中调用全局工具:
 
vue
 
<script setup>
import { ref, onMounted } from 'vue'
import { getClientFingerprint } from '@/utils/fingerprint'

const clientFingerprint = ref('')

onMounted(async () => {
  clientFingerprint.value = await getClientFingerprint() || '获取失败'
})
</script>
 

二、备选方案:手动生成客户端指纹(轻量无依赖)

如果不想引入第三方库,可手动收集浏览器 / 设备特征信息,通过哈希算法生成指纹(唯一性略低于fingerprintjs,但满足简单场景)。

步骤 1:封装手动生成工具函数

javascript
 
运行
 
// src/utils/fingerprint.js
/**
 * 手动生成客户端指纹(轻量无依赖)
 */
export const generateManualFingerprint = () => {
  // 1. 收集客户端核心特征信息(越多特征,唯一性越高)
  const clientInfo = [
    // 浏览器信息
    navigator.userAgent,
    navigator.language,
    navigator.platform,
    // 屏幕信息
    screen.width + 'x' + screen.height,
    screen.colorDepth,
    screen.pixelDepth,
    // 时区与存储信息
    new Date().getTimezoneOffset(),
    !!window.localStorage,
    !!window.sessionStorage,
    // 浏览器功能支持
    !!window.IndexedDB,
    !!window.WebGL,
    navigator.hardwareConcurrency || 'unknown'
  ].join('|') // 拼接为字符串

  // 2. 简单哈希算法(将特征字符串转为32位哈希值,模拟唯一标识)
  const hash = (str) => {
    let h = 0
    for (let i = 0; i < str.length; i++) {
      h = (h << 5) - h + str.charCodeAt(i)
      h |= 0 // 转为32位整数
    }
    return Math.abs(h).toString(16)
  }

  // 3. 生成并返回指纹
  return hash(clientInfo)
}
 

步骤 2:在 Vue3 组件中使用

vue
 
<script setup>
import { ref, onMounted } from 'vue'
import { generateManualFingerprint } from '@/utils/fingerprint'

const clientFingerprint = ref('')

onMounted(() => {
  clientFingerprint.value = generateManualFingerprint()
})
</script>
 

三、关键说明与注意事项

  1. 指纹稳定性
    • fingerprintjs 生成的 visitorId 稳定性较高,浏览器小版本更新、插件安装一般不会改变;
    • 手动生成的指纹受收集的特征影响,屏幕分辨率调整、浏览器语言变更等可能导致指纹变化。
  2. 运行环境
    • 客户端指纹只能在浏览器环境中生成,SSR(服务端渲染)环境下需等待客户端挂载后执行(如onMounted钩子),不可在服务端直接运行。
  3. 隐私合规
    • 客户端指纹涉及用户设备信息,部分地区(如欧盟 GDPR)要求告知用户并获得授权,使用前需符合相关地区的隐私法规。
  4. 唯一性对比
    • 第三方库 fingerprintjs:唯一性>99.5%,适合用户标识、防刷等场景;
    • 手动生成方案:唯一性≈90%,适合轻量需求、无需高精度标识的场景。
在 Vue2 项目中使用fingerprintjs生成客户端指纹,Vue2 与 Vue3 的核心差异在于组件写法(选项式 API 为主)和生命周期钩子fingerprintjs的核心使用逻辑不变,下面提供完整可落地的实现方案。

一、第一步:安装fingerprintjs依赖

与 Vue3 项目一致,直接安装官方最新版即可,它不依赖 Vue 框架版本,仅依赖浏览器环境:
 
bash
 
运行
 
# npm
npm install @fingerprintjs/fingerprintjs --save

# yarn
yarn add @fingerprintjs/fingerprintjs

# pnpm
pnpm add @fingerprintjs/fingerprintjs
 
 
注意:如果你的 Vue2 项目需要兼容 IE11 等旧浏览器,需降级安装fingerprintjs v3 版本(npm install @fingerprintjs/fingerprintjs@3 --save),v4 版本不再支持旧浏览器。

二、第二步:Vue2 项目中使用(3 种常用场景)

Vue2 以选项式 API为核心,所有逻辑写在组件选项中,且需注意生命周期钩子的选择(优先mounted)。

场景 1:直接在单个组件中使用(最简单)

vue
 
<template>
  <div>
    <h3>Vue2 客户端指纹</h3>
    <p>指纹标识:{{ clientFingerprint }}</p>
  </div>
</template>

<script>
// 1. 导入fingerprintjs
import FingerprintJS from '@fingerprintjs/fingerprintjs'

export default {
  name: 'FingerprintDemo',
  data() {
    return {
      // 存储客户端指纹
      clientFingerprint: ''
    }
  },
  // 2. 优先在mounted钩子中执行(确保浏览器环境就绪)
  // Vue2中mounted支持直接使用async/await
  async mounted() {
    try {
      // 3. 初始化指纹库(核心步骤,与Vue3一致)
      const fp = await FingerprintJS.load()

      // 4. 获取指纹结果(visitorId 即为唯一客户端标识)
      const result = await fp.get()

      // 5. 赋值到data中,渲染到页面
      this.clientFingerprint = result.visitorId

      // 可选:打印客户端详细信息
      console.log('客户端详细信息:', result.components)
    } catch (error) {
      console.error('生成客户端指纹失败:', error)
      this.clientFingerprint = '获取失败'
    }
  }
}
</script>
 

场景 2:封装为全局工具函数(多组件复用推荐)

如果多个组件需要使用指纹,建议封装为独立工具函数,方便全局调用。

步骤 2.1:创建工具文件(src/utils/fingerprint.js

javascript
 
运行
 
// src/utils/fingerprint.js
import FingerprintJS from '@fingerprintjs/fingerprintjs'

/**
 * 封装Vue2项目通用的获取客户端指纹函数
 * @returns {Promise<string|null>} 客户端指纹标识(失败返回null)
 */
export const getClientFingerprint = async () => {
  try {
    // 初始化并获取指纹
    const fp = await FingerprintJS.load()
    const result = await fp.get()
    return result.visitorId
  } catch (error) {
    console.error('生成客户端指纹失败:', error)
    return null
  }
}
 

步骤 2.2:在 Vue2 组件中调用工具函数

vue
 
<template>
  <div>全局工具获取指纹:{{ clientFingerprint }}</div>
</template>

<script>
import { getClientFingerprint } from '@/utils/fingerprint'

export default {
  data() {
    return {
      clientFingerprint: ''
    }
  },
  async mounted() {
    // 调用全局工具函数,获取指纹
    this.clientFingerprint = await getClientFingerprint() || '指纹获取失败'
  }
}
</script>
 

场景 3:全局挂载到 Vue 原型(所有组件可通过this直接调用)

如果项目中大量组件需要使用,可将工具函数挂载到 Vue 原型上,无需每次导入。

步骤 3.1:在main.js中全局挂载

javascript
 
运行
 
// src/main.js
import Vue from 'vue'
import App from './App.vue'
import { getClientFingerprint } from '@/utils/fingerprint'

// 挂载到Vue原型上,命名为$getClientFingerprint(推荐加$区分全局属性)
Vue.prototype.$getClientFingerprint = getClientFingerprint

new Vue({
  render: h => h(App)
}).$mount('#app')
 

步骤 3.2:任意组件中直接调用(无需导入)

vue
 
<template>
  <div>原型挂载获取指纹:{{ clientFingerprint }}</div>
</template>

<script>
export default {
  data() {
    return {
      clientFingerprint: ''
    }
  },
  async mounted() {
    // 直接通过this调用全局挂载的函数
    this.clientFingerprint = await this.$getClientFingerprint() || '指纹获取失败'
  }
}
</script>

三、Vue2 项目专属注意事项

  1. 生命周期钩子选择
     
    必须优先使用mounted钩子执行指纹生成逻辑,避免在createdbeforeCreate中执行。虽然 Vue2 的created在 SPA 环境下也能访问window,但mounted是组件挂载到 DOM 后执行,更稳妥(尤其是项目涉及 SSR/NUXT.js v2 时,created可能在服务端执行,会报错缺少navigator/window对象)。
  2. async/await兼容性
     
    如果你的 Vue2 项目未配置 ES6 + 语法兼容(如未安装@babel/plugin-transform-runtime),mounted中直接使用async/await可能报错,此时可改用Promise链式调用:
    javascript
     
    运行
     
    mounted() {
      FingerprintJS.load()
        .then(fp => fp.get())
        .then(result => {
          this.clientFingerprint = result.visitorId
        })
        .catch(error => {
          console.error('生成指纹失败:', error)
        })
    }
    
     
     
  3. Vue2 无组合式 API(默认)
     
    Vue2 默认不支持<script setup>refonMounted等组合式 API,所有逻辑需遵循选项式 API 规范(写在datamounted等组件选项中),切勿直接照搬 Vue3 的写法。
  4. 旧浏览器兼容(可选)
     
    若需兼容 IE11,需降级fingerprintjs到 v3 版本,且使用方式略有差异(v3 初始化无需await):
    javascript
     
    运行
     
    async mounted() {
      // fingerprintjs v3 用法
      const fp = FingerprintJS.load() // 无await
      const result = await fp.get()
      this.clientFingerprint = result.visitorId
    }
    
     

    总结

    1. 生产环境优先使用 @fingerprintjs/fingerprintjs,高效、稳定、唯一性高,且集成简单;
    2. 简单演示或轻量需求可选择手动生成方案,无第三方依赖,打包体积更小;
    3. 无论哪种方案,都需在浏览器客户端挂载后执行,避免环境错误。
    4. Vue2 中使用fingerprintjs核心逻辑与 Vue3 一致(安装→初始化→获取visitorId),差异仅在于组件写法和生命周期钩子。
    5. 优先选择mounted钩子执行,避免环境错误,多组件复用推荐封装工具函数或全局挂载到 Vue 原型。
    6. 如需兼容旧浏览器,需降级fingerprintjs版本,并调整初始化写法,同时保证项目的 ES6 + 语法兼容配置。
    7. 指纹生成仅能在浏览器环境执行,且需遵守相关地区隐私合规要求。
相关新闻