Font Access API 异步获取系统字体列表并渲染到DOM
在前端项目中直接调用用户电脑中已安装的字体,实现个性化的字体预览或设计工具,曾经是一项难以实现的功能。如今,这一局面因一项名为 Font Access API(具体接口为 queryLocalFonts())的浏览器新特性而改变。 简而言之,该API为开发者提供了一条安全访问本地字体列表的途径。它允
在前端项目中直接调用用户电脑中已安装的字体,实现个性化的字体预览或设计工具,曾经是一项难以实现的功能。如今,这一局面因一项名为 Font Access API(具体接口为 queryLocalFonts())的浏览器新特性而改变。
简而言之,该API为开发者提供了一条安全访问本地字体列表的途径。它允许网页在获得用户明确授权后,异步读取系统中已安装字体的元数据信息。需要强调的是,它仅获取字体名称等描述性信息,而非字体文件本身,这从根源上保障了用户数据安全。目前,该功能已在 Chromium 125 及以上版本(包括新版 Chrome、Edge、Opera)中稳定提供,但 Firefox 和 Safari 浏览器尚未支持。

检查支持性与请求权限
在使用前,必须通过两项前置检查:浏览器支持性检测和用户权限请求。该API的权限模型与调用摄像头或地理位置类似——首次尝试访问时会触发明确的授权提示,用户同意后,后续调用方可正常进行。
- 支持性检测:首先确认浏览器是否支持,可通过判断
'fonts' in navigator && 'queryLocalFonts' in navigator.fonts来实现。 - 权限请求:虽然可以通过
navigator.permissions.query({ name: 'local-fonts' })查询权限状态,但实际的授权流程仅在首次调用queryLocalFonts()时触发。这里有一个最佳实践:避免在页面加载时自动调用,以免干扰用户。正确的做法是将其绑定在明确的用户操作上,例如一个“加载本地字体”按钮的点击事件。
异步获取并解析字体元数据
调用成功后,将获得一个由 FontMetadata 对象组成的数组。每个对象都包含了字体的结构化元数据,虽然无法获取.ttf或.otf文件,但以下关键信息足以构建丰富的应用功能:
family: 字体家族名称,即CSS中使用的font-family值,例如 “Inter”、“微软雅黑”。fullName: 字体的完整显示名称,通常包含字重和风格,如 “Inter Bold”、“Microsoft YaHei UI Bold”。postscriptName: PostScript名称,这是许多专业设计软件(如Adobe系列)内部使用的标识符,格式如 “Inter-Bold”。style,weight,stretch: 分别代表字体风格(如italic)、字重(如700)、宽度(如condensed)。利用这些字段,可以轻松筛选出所有“粗体”或“斜体”字体。
以下是一个具体的代码示例,展示了如何获取并整理这些数据:
async function loadLocalFonts() {
try {
const fonts = await navigator.fonts.queryLocalFonts();
console.log(`共发现 ${fonts.length} 款本地字体`);
return fonts.map(f => ({
family: f.family,
fullName: f.fullName,
postscriptName: f.postscriptName,
weight: f.weight,
style: f.style
}));
} catch (err) {
console.warn("获取本地字体失败:", err.message);
return [];
}
}
安全渲染到 DOM(避免样式污染与布局抖动)
获取字体列表后,下一个挑战是如何安全地在页面上展示它们。一个常见的误区是将所有字体名直接应用于全局的CSS font-family 规则。这样做风险较高,可能导致不可预测的字体回退、页面布局抖动(FOIT/FOUT)或样式污染。
更稳妥的方案是为每款字体创建独立的预览容器:
- 为每个字体生成一个如 的DOM元素,并放入标准预览文本(例如 “AaBbYyZz 012345”)。
- 直接通过内联样式设置
style="font-family: '字体名', sans-serif;"。由于字体已安装在用户系统,浏览器会直接调用本地资源渲染,无需网络下载,速度极快。- 如果应用场景要求严格的显示一致性(例如确保跨设备预览效果相同),可以考虑为选中的字体加载网络后备版本。但这需要使用
FontFaceAPI,并且需明确:Font Access API本身不提供任何字体文件的URL或二进制数据。- 出于性能考虑,建议对预览列表进行分页或虚拟滚动处理,避免一次性渲染成百上千条记录,给内存和渲染引擎带来过大压力。
注意事项与兼容性兜底
必须认识到,Font Access API目前仍属于“渐进增强”特性。在生产环境中,完备的降级方案是必不可少的。
- 兼容性回退:当API不可用时,应优雅地回退到预设的网页安全字体列表,或提供一个常见的字体枚举供用户选择。
- 字段差异:避免过度依赖
postscriptName或fullName作为关键逻辑(如字体匹配)的依据,因为它们的格式在Windows、macOS和Linux系统上可能存在差异。 - 字符集验证:并非所有本地字体都包含中文字符。可以通过
document.fonts.check('12px "字体名"')来快速测试该字体是否能渲染当前页面所需的基本字符集。 - 隐私与拦截:在高度关注隐私的环境下,企业的组策略或用户安装的某些浏览器扩展可能会屏蔽此API。因此,代码中必须妥善捕获并处理
SecurityError等异常,以保证应用的健壮性。
- 直接通过内联样式设置
