字体跨域拦截的根因是请求模式、服务端响应头与cdn透传三者未对齐,解决需同步配置:前端@font-face加crossorigin: anonymous,nginx/apache按字体后缀精确配access-control-allow-origin并加always标志,cdn需透传header;若不可控,则用transfonter转base64内嵌。

字体请求被拦截,先看 Network 面板里 woff2 是不是 blocked 或 403
打开 DevTools → Network → 筛选 font,点开那个 .woff2(或 .woff、.ttf)请求,重点看三件事:
• 状态码是不是 blocked:mixed-content(HTTP 页面加载 HTTPS 字体)或 403;
• Response Headers 里有没有 Access-Control-Allow-Origin;
• 如果状态是 200 但字体仍不显示,检查响应体是否为空(说明服务端返回了 header 但没返回字体数据)。
注意:Failed to load resource: net::ERR_FAILED 这类模糊错误,90% 是字体 CORS 被静默丢弃,不是网络不通。
@font-face 必须显式加 crossorigin: anonymous
哪怕 CDN 已配好 CORS 响应头,CSS 里的 @font-face 规则也必须带这一行,否则浏览器默认以非 CORS 模式发起请求,服务端的 Access-Control-Allow-Origin 就完全无效:
• 错误写法:src: url('https://cdn.example.com/icon.woff2') format('woff2');
• 正确写法:src: url('https://cdn.example.com/icon.woff2') format('woff2'); crossorigin: anonymous;
• crossorigin: anonymous 表示不带 cookie,最安全;如果字体请求需携带凭证(如登录态),服务端就不能用 *,得写具体域名,且前端要改用 crossorigin: use-credentials。
Nginx / Apache 必须按后缀精确配置 CORS,且加 always 标志
不能在全局 server 块里简单加 add_header Access-Control-Allow-Origin *,因为 304/404 响应不会带这个 header,导致缓存或路径错误时字体照样失败:
• Nginx 正确配置:
location ~* \.(woff2?|ttf|eot|otf|svg)$ {<br> add_header Access-Control-Allow-Origin "https://yourdomain.com" always;<br> add_header Access-Control-Allow-Methods "GET" always;<br>}
• Apache(.htaccess):
<filesmatch><br> Header set Access-Control-Allow-Origin "https://yourdomain.com"<br></filesmatch>
• 如果用了 CDN(如腾讯云 COS + CDN、阿里云 CDN),确认它透传源站 header;jsDelivr 默认支持字体 CORS,但自定义域名仍要自己配。
实在没法改服务端?直接转 base64 内嵌最稳
当你用的是第三方图标库 CDN(比如 iconfont.cn 的链接),对方不开放白名单配置,或者运维不配合改服务器,base64 是唯一零依赖方案:
• 用 transfonter.org 上传字体文件,选 “Base64 encode”,下载生成的 CSS;
• 只保留 @font-face 块里 src: url(data:font/woff2;base64,...) 这一行,删掉所有外部 url();
• 把这段 CSS 直接塞进项目主样式表,或单独 link 引入;
• 注意:woff2 base64 后体积约增 30%,适合图标字体(几十 KB),不适合大文本字体(几 MB)。
字体跨域问题的核心不在“怎么加 header”,而在于「谁发请求、谁返回 header、谁声明模式」三者必须严格对齐——漏掉 crossorigin: anonymous、服务端没用 always、CDN 不透传 header,任何一个环节出错,字体就静默失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











