技术场景

常用于广告联盟

例如在某个网站上看过某个商品,但没有登录过,过两天用同台电脑访问其他网站时,却发现很多同类商品的广告

实现方式

旧方式

在过去可能使用cookie去追踪用户信息,但cookie可以被用户禁止掉,从而无法追踪,并且无法跨域访问

或者使用浏览器指纹(navigator),它包含:

  • userAgent(用户代理)
    1
    2
    // 包含系统、浏览器版本等信息
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.58"
  • language(浏览器的语言)"zh-CN"
  • platform(操作系统)"Win32"

等信息,但这些指纹不能对某个人进行唯一性标识,也无法对客户端进行唯一性判定

基于HTML5的诸多高级指纹对此提供了新思路

canvas指纹

canvas可以绘制一些图形,游戏等,但它也可以用来跟踪用户

调用toDataURL转换base64时,他底层会获取设备,操作系统,浏览器,三合一的唯一标识

三种条件并非无法同时复现,所以canvas指纹并非唯一,但重复概率也已经很小了

生成canvas指纹

1
2
3
4
5
6
7
8
const uuid = () => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const txt = 'test';
ctx.fillText(txt, 10, 10)
console.log(canvas.toDataURL())
return md5(canvas.toDataURL())
}

生成的Base64(edge):

1
data:image/png;base64,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

生成的Base64(chrome):

1
data:image/png;base64,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

两个浏览器生成的base64串不同,但图片是一样的

如果base64太长,可以进行MD5压缩或crypto

防止跟踪

安装随机修改canvas指纹的浏览器插件(CanvasFingerprintBlock)

原理:每次随机往canvas画布里注入一个随机的噪音(肉眼是看不到的),从而影响base64加密结果