Linux armv81 浏览器信号:平台边界
解读 Linux armv81、User-Agent Client Hints 与 WebGL,不把浏览器表面当作硬件身份。
BotBrowser Team
页面显示 Linux armv81 时,重要问题不是它对应哪一部手机,而是这段文字来自哪个可见字段、哪些可选字段没有返回,以及能力是否一致。Android 模拟文档说明 BotBrowser 为什么可以呈现这类平台表面,但这段字符串不是设备标识符。
TL;DR
navigator.platform是页面可见字符串,不是 CPU 型号或个人身份。- User-Agent Reduction 与 User-Agent Client Hints 的可用条件不同;缺少 hint 不等于否定值。
- WebGL 可以说明某个上下文的能力,缺少扩展不能证明主机不同。
unknown、not-requested、not-exposed和真实值必须分开保存。- 一致性记录应说明观察到了什么、在哪里观察,以及哪些比较无法完成。
Contents
- 平台字符串只是一个字段
- 缩减 User-Agent 与 Client Hints
- 作为能力证据的 WebGL
- 保留未知状态的一致性记录
- 失败情况与解释边界
- 诊断平台差异
- BotBrowser 文档边界
- 实践结论
平台字符串只是一个字段
Navigator.platform 向网页提供字符串。它不承诺物理 CPU、内核、设备型号或用户身份。/docs/platform/android-emulation/ 中的 Linux armv81 是平台表面的示例,不是每个 profile 或 WebView 都必须返回的结果。
| 字段 | 可记录的观察 | 不能证明 |
|---|---|---|
navigator.platform | 原样字符串,例如 Linux armv81 | 物理 CPU、型号或个人 |
navigator.userAgent | 页面实际返回的 UA 文本 | 完整主机系统 |
navigator.userAgentData | 可用的低熵值 | 高熵 hint 已获准 |
uaData.architecture | 未请求时为 unknown | 物理架构 |
| WebGL | 上下文、扩展和参数 | 唯一 GPU 或检测结论 |
可以把平台字符串用于兼容性分支,但不能把 platform.includes('arm') 当作授权条件。若 profile 之间不同,应记录改变的配置,而不是推断设备改变。
缩减 User-Agent 与 Client Hints
User-Agent Reduction 会从默认 UA 中移除部分系统和设备细节。NavigatorUAData 提供基础值,也可通过 getHighEntropyValues() 请求可选值。User-Agent 缩减指南解释请求头迁移,WebGL renderer 边界指南则把图形能力与设备身份分开。
| 观察 | 稳妥解释 | 不稳妥替换 |
|---|---|---|
| 接口不存在 | 当前上下文未暴露 | 不是 Chromium |
存在 platform | 返回了宽泛平台 token | 完整操作系统 |
请求后返回 architecture | 此上下文返回了该 hint | 物理芯片 |
| Promise 被拒绝 | 请求不可用或被拒绝 | 架构不是 ARM |
async function readPlatformSurface() {
const result = {
platformString: typeof navigator.platform === 'string' ? navigator.platform : 'not-exposed',
userAgent: navigator.userAgent || 'not-exposed',
uaData: 'not-exposed',
highEntropy: 'not-requested',
};
if (!navigator.userAgentData) return result;
result.uaData = { mobile: navigator.userAgentData.mobile, platform: navigator.userAgentData.platform };
try {
result.highEntropy = await navigator.userAgentData.getHighEntropyValues([
'architecture',
'model',
'platformVersion',
]);
} catch {
result.highEntropy = 'request-failed';
}
return result;
}
作为能力证据的 WebGL
WebGLRenderingContext 描述图形上下文的调用和参数。上下文创建成功、扩展为 null 或创建失败,都是能力状态,不是 ARM 硬件证明。
| 观察 | 可以支持 | 不能证明 |
|---|---|---|
| 成功创建上下文 | 页面获得了该能力 | 物理 GPU |
getExtension() 为 null | 此处缺少扩展 | 所有主机都缺少 |
| 参数返回值 | 此参数在此处暴露 | 唯一身份 |
| 创建失败 | 这次请求未执行 | 没有更多诊断时的原因 |
保留未知状态的一致性记录
最小记录应保留上下文、原始平台字符串、UA-CH 请求状态和具体 WebGL 调用。architecture: unknown 代表没有获得结果,不代表 x86。比较时先核对浏览器版本和上下文,再比较字段,最后比较图形操作。
| 键 | 示例 | 规则 |
|---|---|---|
context | Window / secure | 记录读取位置 |
platformString | Linux armv81 | 保留原文字串 |
uaData.architecture | unknown | 不填补缺失 |
webgl.context | webgl2 | 记录请求的上下文 |
webgl.extension | available / absent | 写出扩展名称 |
失败情况与解释边界
出现平台字符串但缺少高熵 hint 时,应保留 unknown 并检查请求是否执行。WebGL2 失败时检查上下文、策略和异常,不要修改平台标签。不同上下文的字符串需要先比较 profile、版本和嵌入模式。hint 返回的型号仍是浏览器值,不是物理设备证明。
诊断平台差异
先记录窗口上下文,再原样保存 navigator.platform 和 navigator.userAgent。记录 navigator.userAgentData 是否存在、返回了哪些低熵键,以及高熵请求的结果。接口缺失和 Promise 被拒绝是不同状态。
WebGL 只记录请求的上下文、getContext() 结果和解释应用决策所需的参数。调用抛出异常时保留异常类别,不要用猜测值替代。
| 步骤 | 保留的证据 | 停止条件 |
|---|---|---|
| 安全窗口 | isSecureContext 与上下文 | 无效上下文不请求 hint |
| 平台 | navigator.platform 原文 | 不映射为设备型号 |
| UA-CH | 接口、键和结果 | 缺失值保持未知 |
| WebGL | 类型与相关扩展 | 不扩展成 renderer 清单 |
| 对比 | 相同版本、profile 与 fixture | 不比较不同输入 |
| 观察 | 稳妥解释 |
|---|---|
未请求 architecture | 没有请求,不是否定架构 |
architecture 被拒绝 | 策略或上下文拒绝了请求 |
Linux armv81 且 WebGL2 失败 | 两个独立观察,应在相同上下文复现 |
这样的记录用于复现兼容性问题,不用于识别人或设备。
BotBrowser 文档边界
BotBrowser 文档描述 Android 模拟的平台表面,但不保证每个 Client Hint、具体 WebGL 后端或第三方检测结果。配置是配置证据,页面读取是观察证据;二者都不承诺匿名性、通过率或个人身份。
BotBrowser 可以呈现配置好的平台表面用于兼容性复核,但不保证每个 Client Hint、WebGL renderer 或外部检测结果。
FAQ
Linux armv81 能证明 Android 吗?
不能。它是页面可见字符串,可能与 Android 表面一致,但不能证明内核或设备。
缺少 architecture hint 就是 x86 吗?
不是。缺失、未请求和被拒绝是不同状态。
WebGL 能识别 ARM 设备吗?
不能。它描述具体上下文的能力,不提供物理身份。
这份记录能识别人或设备吗?
不能。它保存页面可见值和可用状态,用于诊断而不是创建身份。
Sources
可继续阅读平台表面复核地图和navigator 属性信号指南。
实践结论
把 Linux armv81 当作一个可见字段。保存原始字符串、缩减 UA、每个 Client Hint 的请求状态和具体 WebGL 能力;没有返回的值保持未知。这样可以排查兼容性,不会把平台家族误写成硬件、个人或检测结论。
本文属于指南: 什么是浏览器指纹?原理、风险、信号与隐私边界