Angular 13中通过服务加载租户CSS时字体无法加载的问题
Angular 13租户专属字体加载问题:CSS加载成功但字体未加载
问题场景
在Angular 13中实现租户专属样式时遇到异常:
- 直接在
app.component.ts中执行动态加载租户CSS的代码时,tenant-a.css及关联字体均成功加载,页面文本正常应用新字体。 - 将相同加载逻辑封装到
ThemeService的loadTheme()方法,并在app.component.ts的ngOnInit中调用时,仅tenant-a.css加载成功,字体资源未被浏览器请求。
已做尝试:
- 在
angular.json中设置styles的inject为false - 尝试在服务中添加延迟加载,问题未解决
- 因租户数量多(30个)且字体各不相同,无法全局加载所有字体
解决步骤
1. 服务中正确注入Angular的DOCUMENT对象
避免直接使用window.document,改用Angular提供的DOCUMENT令牌注入,确保样式加载的上下文与Angular应用一致:
import { Inject, Injectable } from '@angular/core'; import { DOCUMENT } from '@angular/common'; @Injectable({ providedIn: 'root' }) export class ThemeService { constructor(@Inject(DOCUMENT) private document: Document) {} loadTheme(): void { const headEl = this.document.querySelector('head')!; // 避免重复加载同一主题CSS const existingLink = this.document.querySelector('link[href="tenant-a.css"]'); if (existingLink) return; const newLinkEl = this.document.createElement('link'); newLinkEl.rel = 'stylesheet'; newLinkEl.href = 'tenant-a.css'; // 解决跨域字体加载问题 newLinkEl.crossOrigin = 'anonymous'; // CSS加载完成后触发浏览器重绘,确保字体被检测并应用 newLinkEl.onload = () => { const body = this.document.body; body.style.display = 'none'; void body.offsetHeight; // 强制触发重绘 body.style.display = ''; }; headEl.appendChild(newLinkEl); } }
2. 修改字体路径为绝对路径
CSS中字体的相对路径是相对于CSS文件本身的位置,若CSS加载路径导致字体解析错误,会出现CSS加载成功但字体404的情况。改用绝对路径(以/开头)确保字体路径不受CSS文件位置影响:
@font-face { font-family: 'Pilat Wide'; font-style: normal; font-weight: 400; font-display: auto; src: url('/assets/fonts/pilatwide/PilatWide-Regular-woff2.woff2') format('woff2'); } @font-face { font-family: 'Pilat Bold'; font-style: bold; font-weight: 600; font-display: auto; src: url('/assets/fonts/pilatwide/PilatWide-Bold-woff2.woff2') format('woff2'); }
3. 检查浏览器控制台的错误提示
打开浏览器开发者工具的Console面板,排查字体加载失败的具体原因:
- 若为404错误:确认字体文件的绝对路径是否正确,检查文件是否存在于指定位置
- 若为CORS错误:在服务器配置中添加字体文件的跨域访问权限,或确保link标签已添加
crossorigin="anonymous"属性
4. 确保页面元素正确引用字体
确认全局样式或组件样式中已设置使用租户字体,例如:
body { font-family: 'Pilat Wide', sans-serif; } .bold-text { font-family: 'Pilat Bold', sans-serif; }
内容的提问来源于stack exchange,提问作者Anderson
相关产品推荐
相关产品推荐

