#嵌入字体的方法

ZSFT 中有五大嵌入方法: 常规 CSS 、HTML 强化、HTML 无阻塞、高级冗余.js 和 英文子集化,当然,前四个实际上都是编写好的代码,可以自己实现。

#常规 CSS

这是最通用也是推荐的方法,任何字体都会提供 “常规 CSS” 选项,可以将它使用在 .css 文件或 HTML 的 <style> 中。

/* 大体积字体,按需加载 */
@import url('https://fontsapi.zeoseven.com/1/main/result.css');

body {
      font-family: "JinzisheTongfang";
      font-weight: normal;
}

/* 小体积字体,完整字库和冗余 */
@font-face {
      font-family: "zsft-a";
      src: url('https://fontsapi.zeoseven.com/a/main.woff2') format('woff2'),
          url('https://fontsapi-storage.zeoseven.com/a/main.woff2') format('woff2');
      font-display: swap;
}
body {
      font-family: "zsft-a";
      font-weight: normal;
}

通常用于: CSS

需要使用 <style> 包裹的: HTML

优点: 更高的加载优先级,字体被缓存后无闪烁, WebFonts 的标准方法

缺点: 会阻塞 HTML 渲染

提供: 任何字体

#HTML 强化

此选项可以被用在 HTML 或 PHP 中,以标准方法实现预载和冗余措施。

<link rel="preconnect" href="https://fontsapi.zeoseven.com" crossorigin />
<link rel="stylesheet"
    href="https://fontsapi.zeoseven.com/1/main/result.css"
    onerror="this.href='https://fontsapi-storage.zeoseven.com/1/main/result.css'"
/>
<style>
    body {
        font-family: "JinzisheTongfang";
        font-weight: normal;
    }
</style>

通常用于: HTML

优点: 更高的加载优先级,字体被缓存后无闪烁,加载冗余

缺点: 会阻塞 HTML 渲染

提供: 仅大体积字体

#HTML 无阻塞

此选项可以解决常规 <link> 加载 CSS 阻塞渲染的问题,但可能导致字体闪烁,同时使用 noscript 标签确保兼容性。

<link rel="preload" as="style" crossorigin
    href="https://fontsapi.zeoseven.com/1/main/result.css"
    onload="this.rel='stylesheet'"
    onerror="this.href='https://fontsapi-storage.zeoseven.com/1/main/result.css'"
/>
<noscript>
    <link rel="stylesheet" href="https://fontsapi.zeoseven.com/1/main/result.css" />
</noscript>
<style>
   body {
       font-family: "JinzisheTongfang";
       font-weight: normal;
   }
</style>

通常用于: HTML

优点: 更低的加载优先级,无阻塞 HTML 渲染,加载冗余

缺点: 字体被缓存后仍然闪烁,客户端未开启 JavaScript 会导致无效

提供: 仅大体积字体

#高级冗余.js

将会在字体的详情页提供一段 JS 代码动态的加载字体,实现当 CDN 出现错误时立即直接由源服务器提供文件来始终不断的加载字体,适合 React / Vue3 等客户端路由场景。

通常用于: JavaScript

需要使用 <script> 包裹的: HTML

优点: 更低的加载优先级,无阻塞 HTML 渲染,加载冗余

缺点: 在非 SPA 等客户端路由中字体被缓存后仍然闪烁,客户端未开启 JavaScript 会导致无效

提供: 仅大体积字体

#英文子集化

提供一个静态的子集化的 WOFF2 文件,其中包含一小部分字符,用于只需要字体的英文字符和数字的情况下,因为此选项只需要加载 10KB 左右的文件,将庞大的 CJK 字体子集化为英文字体,字符有:

AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890 ,.!?:;-
@font-face {
      font-family: 'zsft-enmin-1';
      src: url('https://fontsapi.zeoseven.com/1/main.woff2') format('woff2'),
          url('https://fontsapi-storage.zeoseven.com/1/main.woff2') format('woff2');
      unicode-range: U+0061-007A, U+0041-005A, U+0030-0039, U+002E, U+002C, U+0021, U+003F, U+003A, U+003B, U+002D;
}

body {
      font-family: "zsft-enmin-1";
      font-weight: normal;
}

通常用于: CSS

需要使用 <style> 包裹的: HTML

优点:更高的加载优先级,字体被缓存后无闪烁, WebFonts 的标准方法,加载更快

缺点:会阻塞 HTML 渲染,字库字符缺失

提供:仅大体积字体

#字体收录 FAQ

出于对知识产权的尊重及保护和对使用 WebFonts 用户的法律风险负责,所以字体的许可协议需要满足三个条件才能收录:

免费商用 或 开放非盈利性使用
允许转换和二次分发
允许嵌入

常见的满足条件的许可协议: OFL / MIT / Apache / GPL

需要被特殊处理的许可协议: IPA

明确不允许的许可协议: CC BY-NC

#热门的无法收录字体

MiSans / vivo Sans    其许可协议不允许 二次分发,故提供 WebFont 将违反协议。
HarmonyOS Sans    其许可协议不允许 单独二次分发,故提供 WebFont 将违反协议。
* 阿里妈妈系列    其许可协议不允许 转换、拆分,无法提供 WebFont ,除非系列内具有例外。

#无法正常提供的字体

以下字体在提交收录申请后,即便是转换格式,也无法被子集或切割,或者最终输出乱码或字符错位而无法提供或无效的提供 WebFont 。

ChillMovableType / 活字印刷字体项目 / 包括此系列字体
    github.com/Warren2060/ChillMovableType
        [V1.000] 不转换(.otf)切割则字符为空白或缺字,转换后(.ttf)切割出现乱码,西文错位。

ChosunNm / ChosunilboNM / 조선일보명조 / 朝鲜日报明朝体
    event.chosun.com/100/100font.html
        [V001.300 & V001.400] 切割后加载到浏览器测试时无法解析字体元数据表导致 OTS 问题而无法加载。

#错误示例

#将 CSS 错误的使用 @font-face 引入

@font-face {
      font-family: "自定义名称";
      src: url('https://fontsapi.zeoseven.com/2/main/result.css');
}

这将导致无法正确引入字体, @font-face 只能引入 ttf, otf, eot, woff, woff2 等字体源文件, CSS 文件需要使用 link 标签或 @import 引入。

#按需加载的痛

@font-face {font-family: "自定义名称";src:local("自定义名称"),url("https://fontsapi.zeoseven.com/2/main/0601a1cb4a9f56b374f91d612855ddad.woff2") format("woff2");font-style: normal;font-weight: 400;font-display: swap;}
@font-face {font-family: "自定义名称";src:local("自定义名称"),url("https://fontsapi.zeoseven.com/2/main/5e12300c47a34e65160bae82763f87e6.woff2") format("woff2");font-style: normal;font-weight: 400;font-display: swap;}
/* 此处省略很多 @font-face */

html {
      font-family: "自定义名称";
}

这导致了 分包的无效、按需加载的无法工作 及 字体更新后的难以跟进甚至中断。应直接使用 link 标签或 @import 引入可能提供的 CSS 文件。

#违法违规内容的定义和处理措施

ZSFT 和第三方 CDN 提供商是位于中国的已备案 CDN 服务,严格遵守《网络安全法》等法律法规,拒绝为含违法违规内容的主体提供服务。即便它禁止中国大陆的访客访问。

本机制遵循 “技术中立” 原则,对符合中国法律法规的境外网站保持服务中立。网络运营商公网 IP 原则上不纳入拦截范围,正常用户使用不受影响。

覆盖主体

IPv4, IPv6, CIDR/IP, Domain

该机制只影响 fontsapi.zeoseven.com 。

#处理措施

ZSFT 将使用包括但不限于让 fontsAPI 返回 403 响应码的措施来导致相关字体资源无法加载。

法律声明

本机制依据《网络安全法》第十六条及《互联网信息服务管理办法》第十五条设立,系保障 ZSFT fontsAPI 服务合规运营的必要措施。

#误封申诉

有时, ZSFT 可能会误判导致域名或 IP 被列为违法违规内容,则您可以 联系我们 并表明被误判的域名或 IP 及合法性证据和误判原因。

#fontsAPI 响应标头

fontsapi.zeoseven.com 和 fontsapi-storage.zeoseven.com 的响应标头中,具有一定的相似度,它们都具有以下响应:

#Cache-Control

public, max-age=31536000, immutable

这指定了客户端和边缘服务器的缓存行为,即 1 年时间且不会改变,这意味着客户端只需要加载一次这款字体,那么客户端的浏览器将保留字体文件 1 年时间,但因为浏览器的缓存行为和存储空间,实际上可能无法达到 1 年的缓存时长。

#Access-Control-Allow-Origin

*

这指定了任何主机名都可以对其中的资源进行跨域请求,这是常见的跨域响应标头且必须。

#Access-Control-Allow-Methods

GET, OPTIONS, HEAD

这指定了跨域请求允许的请求方法,通常来说,静态资源只需要 GET, OPTIONS 和 HEAD 方法即可满足使用需求。

#Access-Control-Max-Age

31536000

跨域请求会首先发出预检请求来确认目标服务器是否允许跨域,而此标头指定了跨域请求在发出预检请求后,允许跨域或不允许跨域应该保留 1 年,即最大时间 1 年内都不需要再次发出预检请求确认是否允许跨域。

#Access-Control-Allow-Credentials

false

这指定了不允许跨域请求携带凭据,当然携带凭据也没有什么作用,因为 ZSFT fontsAPI 完全静态。

#热度值

记录 过去 30 天 内字体的累计统计数据,热度值 会下降和上升,以 层级 表示。

热度值从来不是一个准确的数字,如果热度值为最低的 100 ,那将代表这款字体在过去一个月 从未被 点击、查阅或搜索(包括搜索引擎),那将是糟糕的,而在之后的层级,数字越大,代表过去一个月内被 点击、查阅或搜索 的次数越多,如 1k、2k、3k ... 9k、1w ... 没有上限

当然,这不过代表字体在 ZSFT 中的受欢迎程度。和 ZSFT 站点的流量密切相关。