CDN 上的字体文件加载失败?排查 CORS、缓存响应头与跨域预检
本内容发表于:2026-09-18 16:19:34
浏览量
1031

页面能打开,图片和 CSS 也正常,文字却退回系统字体。打开浏览器开发者工具后,woff2 请求可能显示 200,控制台仍报 CORS 错误。只看 HTTP 状态码容易误判:请求到了 CDN,浏览器却未获准把响应交给页面使用。

这篇教程适用于字体文件放在独立静态域名或 CDN 域名上的网站。先找出请求和响应头,再判断问题发生在源站、CDN 缓存还是浏览器的跨域规则。

先确认失败的是哪一个请求

在浏览器开发者工具的 Network 面板筛选 font 或 woff2,重新加载页面,记下页面域名、字体 URL、请求方法、状态码以及响应头。重点核对 Access-Control-Allow-Origin。同域名下不同端口或协议,也属于不同源。

如果字体 URL 返回 404 或 403,先处理路径和访问权限;如果返回的是 HTML 错误页,排查 CDN 回源和重写规则。只有响应确实是字体文件、控制台又出现跨域拦截时,才继续检查 CORS。

跨源字体请求遵循 CORS 规则。浏览器发出的请求通常带 Origin;允许公开读取的字体资源,可以在实际的字体响应中返回 Access-Control-Allow-Origin: *。如果只允许特定站点,就返回该站点的完整源,例如 https://www.example.com,不要写成路径或用逗号拼接多个源。

分开检查源站与 CDN 返回的头

在能访问源站和 CDN 的终端上,用 GET 请求模拟页面来源;把示例域名换成自己的。curl 只用于看响应头,它不会替浏览器执行 CORS 校验。

curl -sS -D - -o /dev/null \
  -H 'Origin: https://www.example.com' \
  'https://static.example.net/fonts/site.woff2'

记录状态码、Content-Type、Access-Control-Allow-Origin、Vary 和 CDN 的缓存状态头。再以相同 URL、相同 Origin 检查源站直连响应。若源站有允许来源的响应头、CDN 没有,检查 CDN 响应头规则、缓存中的旧对象及回源时是否转发了 Origin。若两边都没有,先改源站的字体资源响应。

需要核对响应体时,可下载一个临时副本并确认它是字体文件,不要把 200 的 HTML 错误页当成字体响应。修改配置后分别测试全新 URL 和旧 URL,可以区分“规则仍未生效”和“旧缓存仍在服务”。

按字体使用方式设置允许来源

公开访问、不携带跨域凭据的静态字体通常可以使用 Access-Control-Allow-Origin: *。若业务要求限定来源,应按可信站点白名单动态返回单一来源,并配合 Vary: Origin;同时确认 CDN 的缓存键或响应头规则会正确区分不同来源。只写 Vary: Origin,不能保证每家 CDN 都按 Origin 分别缓存。

下面是 Nginx 的示例配置,适用于公开读取的字体文件;先在测试环境确认站点现有 location、缓存头和访问控制,不要直接复制覆盖原配置。

location ~* \.(woff2?|ttf|otf)$ {
    add_header Access-Control-Allow-Origin * always;
    add_header X-Content-Type-Options nosniff always;
}

修改前备份相关配置;运行 nginx -t 通过后再平滑重载。Nginx 的 add_header 存在配置层级继承规则:在子级重新定义响应头后,要确认原有缓存或安全头没有意外消失。若反向代理或 CDN 已配置 CORS 响应头,也要避免重复返回互相冲突的 Access-Control-Allow-Origin。

为什么看到 OPTIONS,不一定是字体请求触发的

普通跨源字体 GET 通常不会单独触发预检。Network 面板若出现 OPTIONS,先检查它对应的 URL 和实际请求方法:它可能属于同页面的 API,也可能是前端额外加了非简单请求头。预检响应需要与对应的跨源请求匹配;不要把 API 的 OPTIONS 错误直接归因于字体文件。

如果请求使用凭据,通配符 * 不能与凭据式 CORS 响应配用,需要返回明确的源并检查 Access-Control-Allow-Credentials。对于公共字体,通常没必要携带 cookie;先检查前端是否无意中把跨域凭据带进请求链路。

修好后怎样验证

清除相关 CDN 缓存或等旧缓存到期,然后用无痕窗口重新加载页面。确认字体请求的响应头有正确的允许来源,控制台不再报 CORS,Computed 面板显示预期字体。再测试另一个页面来源和一个不在白名单内的来源,避免修好一个站点却把限制全部放开。

如果新 URL 正常、旧 URL 仍失败,优先排查 CDN 缓存和响应头规则的生效范围;如果源站、CDN 的头都正确而浏览器仍失败,核对实际发出的请求 URL、重定向链、凭据模式及控制台完整错误信息。排障时保留一次完整的请求/响应头记录,比反复盲目修改 CORS 规则更有效。

参考资料

  1. MDN:Cross-Origin Resource Sharing

  2. MDN:Access-Control-Allow-Origin

  3. MDN:Vary

  4. Cloudflare Docs:CORS and cached assets

  5. NGINX Docs:ngx_http_headers_module

资料核验:2026-09-18。