FingerprintJS 绕过广告拦截器:开源自托管与商业替代方案完全指南
【免费下载链接】fingerprintjsThe most advanced free and open-source browser fingerprinting library项目地址: https://gitcode.com/GitHub_Trending/fi/fingerprintjs
某些广告拦截器可能会基于已知的 CDN 域名或脚本文件名,检测并拦截 FingerprintJS 这类浏览器指纹库的加载。本文基于 FingerprintJS 仓库中的 docs/evade_ad_blockers.md 展开,系统梳理拦截发生的原理、开源侧(NPM 安装 / 自托管脚本)与商业侧(Fingerprint Pro 自定义子域名)的绕行方案,并结合作仓库源码(src/agent.ts、src/sources/dom_blockers.ts 等)验证各方案的底层行为。读完本文,你将掌握:如何判断自己命中了哪条拦截规则、如何在开源免费的前提下稳定加载指纹库、以及何时应该转向商业方案。
拦截是如何发生的
FingerprintJS 官方 CDN 提供的脚本 URL 是固定且公开的,例如:
https://openfpcdn.io/fingerprintjs/v5广告拦截器维护的规则列表中,常见做法是按“域名 + 路径 + 文件名”的组合特征命中脚本。一旦你的页面以<script>标签或动态import()的方式加载上述地址,就可能触发规则而被拦截。仓库 readme.md 中的 CDN 示例也明确提示了这一点:
If you're using an ad blocker or Brave/Firefox, this import will not work. Please use the npm package instead.
这正是官方推荐改用 NPM 包的原因。
绕行的第一步是先确认拦截规则:不同拦截器(uBlock Origin、AdGuard、Brave Shields 等)使用的规则集不同,命中条件也不同。你应当先在目标浏览器中关闭/开启拦截器、逐一排查是哪一条规则(针对域名、路径还是文件名)导致了加载失败,再选择下文对应的方案。
开源方案一:通过 NPM 安装(首选)
将 FingerprintJS 作为依赖打包进你的应用,是官方最推荐的绕过方式。脚本代码被打包进你自己的 bundle 中,不再引用任何已知的指纹库 CDN 域名,广告拦截器没有现成规则可以命中。
安装与使用
# 安装包(当前仓库 package.json 中版本为 5.2.0) npm i @fingerprintjs/fingerprintjs # 或 yarn add @fingerprintjs/fingerprintjsimport FingerprintJS from '@fingerprintjs/fingerprintjs' // 在应用启动时初始化 agent const fpPromise = FingerprintJS.load() ;(async () => { // 在真正需要标识符时再调用 get() const fp = await fpPromise const result = await fp.get() console.log(result.visitorId) })()此方案适用于 Webpack、Rollup、Vite 等任何支持 ESM 的构建工具,也支持 CommonJS(require('@fingerprintjs/fingerprintjs')),完整 API 参考见 docs/api.md 中的“Webpack/Rollup/NPM/Yarn”一节。
需要知晓的行为差异:monitoring 统计请求
与 CDN 版本不同,通过 NPM 安装运行时,库会向 FingerprintJS 服务器发送匿名的 AJAX 请求用于收集安装统计。相关实现位于 src/agent.ts 的monitor()函数:
function monitor() { // CDN 会通过 window.__fpjs_d_m 标记,跳过统计 if (window.__fpjs_d_m || Math.random() >= 0.001) { return } const request = new XMLHttpRequest() request.open('get', `https://m1.openfpcdn.io/fingerprintjs/v${version}/npm-monitoring`, true) request.send() }结合 docs/api.md 的说明,该请求具备以下特征:
- 低概率触发:
load()运行时只有 0.1% 的概率发出请求(即源码中的Math.random() >= 0.001); - 低频次:同一浏览器实例每周最多发送一次(除非浏览器缓存被清除);
- 内容匿名:仅包含库版本、客户端发送的 HTTP 头(含页面 origin 与 referrer)以及客户端 IP。
如果你希望彻底关闭该请求,可在load()时传入monitoring: false(LoadOptions定义见 src/agent.ts):
const fpPromise = FingerprintJS.load({ monitoring: false })CDN(openfpcdn.io)分发的脚本默认就关闭了 monitoring(window.__fpjs_d_m被替换为true),因此该选项主要影响自托管与 NPM 两种使用方式。
开源方案二:自托管脚本(次选)
如果不便改造构建流程,也可以将脚本下载后放到自己的域名下。仓库文档明确提示这是不太推荐的方式,原因有二:
- 更新滞后:自托管版本不会自动跟随上游发布,随着新浏览器不断发布,脚本可能很快过时甚至失效;
- 路径敏感:务必确保脚本 URL 不以
/fingerprint.js结尾,否则仍会被拦截规则命中。
你可以从官方 CDN 下载脚本文件(可把版本号替换为具体版本,例如v5.0.0):
- ES Module 版:
https://openfpcdn.io/fingerprintjs/v5/esm.min.js - UMD 版:
https://openfpcdn.io/fingerprintjs/v5/umd.min.js
另外,docs/api.md 中的<script>标签方式还提供了同步加载版本:
https://openfpcdn.io/fingerprintjs/v5/iife.min.js将下载后的文件改名(避免/fingerprint.js等特征名)、部署到自有域名,再以本地相对路径引用即可。例如:
<script src="/assets/vendor/fp/v5.js"></script> <script> var fpPromise = FingerprintJS.load() fpPromise.then(fp => fp.get()).then(result => console.log(result.visitorId)) </script>自托管方案的本质是“换域名 + 换文件名”,让广告拦截器无法通过已知 URL 特征定位脚本。
商业方案:Fingerprint Pro
如果业务对识别准确率、稳定性和防绕过能力有更高要求,官方提供了商业化的 Fingerprint Identification(Pro)作为替代:
- 14 天免费试用:注册后包含无限 API 调用,支持 CDN 与 NPM 两种安装方式,并提供自定义子域名能力。自定义子域名意味着指纹脚本由你专属的域名提供,广告拦截器无法通过域名特征预判拦截,从而从根本上规避检测;
- 付费档:支持每月无限次识别事件,同样同时支持 CDN、NPM 安装方式与自定义子域名功能。
需要说明:Fingerprint Pro 与开源 FingerprintJS 的能力差异见 docs/comparison.md,商业方案的注册与接入在其自有平台进行,本文不展开外部操作细节。
方案对比与选型建议
| 方案 | 是否需要构建流程改造 | 更新维护成本 | 被广告拦截器命中的风险 | 额外行为 |
|---|---|---|---|---|
| NPM 安装(开源) | 需要(打包进 bundle) | 低,随依赖升级 | 极低 | 存在 0.1% 概率的 monitoring 请求,可用monitoring: false关闭 |
| 自托管脚本(开源) | 不需要 | 高,需手动跟随版本更新 | 低(注意 URL 不能以/fingerprint.js结尾) | 无 |
| Fingerprint Pro(商业) | 可选 | 由服务方维护 | 极低(自定义子域名) | 服务端处理,准确率与防篡改能力更强 |
选型建议:
- 项目已使用模块化构建工具,优先选择 NPM 安装,这是官方推荐的默认路径;
- 无法改造构建流程、仅需快速上线的静态页面,选择自托管,但务必在 URL 命名和版本更新上做好规划;
- 对准确率、风控与稳定性有生产级要求,评估 Fingerprint Pro 的试用方案。
附:广告拦截器与指纹库的双向博弈(源码视角)
值得一提的是,FingerprintJS 自身就内置了一个与广告拦截器相关的熵源domBlockers,用于检测页面命中了哪些广告过滤规则,实现见 src/sources/dom_blockers.ts,并在 src/sources/index.ts 中以domBlockers: getDomBlockers注册为内置熵源。它仅在 Safari 与 Android 浏览器上生效(这些浏览器在隐私模式下仍保留内容拦截器),通过批量创建 CSS 选择器对应的 DOM 元素、检查offsetParent是否为空来判断拦截是否发生,并按“单个过滤器命中超过 60% 的选择器”判定该过滤器处于启用状态(相关阈值逻辑见 src/sources/dom_blockers.ts)。
这说明“广告拦截器试图拦截指纹库”与“指纹库利用拦截器特征增强识别”是一对共生的攻防关系:如果你的页面同时启用了广告拦截器和 FingerprintJS,get()返回的components.domBlockers会带有拦截器过滤器的信号。这一熵源的维护方式(过滤器列表如何生成与更新)可参考 docs/content_blockers.md。
延伸阅读
- docs/api.md:完整 API 参考、全部安装方式、
load()参数(delayFallback/debug/monitoring)说明 - docs/content_blockers.md:
domBlockers熵源的过滤器列表维护指南 - docs/browser_support.md:支持浏览器范围与旧浏览器运行方式
- docs/typescript_support.md:TypeScript 集成与类型错误排查
- docs/version_policy.md:指纹算法版本与 API 兼容策略
- src/agent.ts:
load()/monitor()/get()的实现细节 - src/sources/dom_blockers.ts:广告拦截器检测熵源实现
【免费下载链接】fingerprintjsThe most advanced free and open-source browser fingerprinting library项目地址: https://gitcode.com/GitHub_Trending/fi/fingerprintjs
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考