javascript 中无法直接取消浏览器已发起的字体加载请求,因为 fetch 或 xmlhttprequest 等标准 api 不支持对字体资源进行中止操作。要解决此问题,需通过拦截网络请求并返回空响应来模拟取消效果,具体做法是监听 fetch 事件或使用 service worker 拦截 font-face 请求,并在检测到取消信号时返回空的 arraybuffer 或 blob,从而阻止字体下载。

如何通过 fetch 拦截器取消字体请求
使用原生 fetch 拦截器可以捕获所有网络请求,当检测到目标为字体文件且需要取消时,立即返回一个空的 Response。这种方法适用于单页应用(SPA)中动态加载字体的场景,例如用户切换语言或主题时,旧字体不再需要,可通过拦截器将其“取消”。

const originalFetch = window.fetch;
window.fetch = async function(url, options) {
if (url.endsWith('.woff2') && shouldCancelFont()) {
return new Response('', { status: 204 });
}
return originalFetch.apply(this, arguments);
};
function shouldCancelFont() {
// 根据业务逻辑判断是否取消
return isFontLoadingCancelled;
}
上述代码中,shouldCancelFont() 是一个自定义函数,用于判断当前是否需要取消字体加载。如果返回 true,则拦截器返回状态码为 204 的空响应,浏览器将不会下载该字体。注意,此方法仅适用于通过 fetch 发起的请求,对于 CSS 中 @font-face 声明的字体,需结合其他策略。
Service Worker 如何拦截字体请求
Service Worker 可以在更底层拦截网络请求,适合处理全局字体加载取消需求。通过注册 fetch 事件监听器,可对所有字体请求进行检查,若满足取消条件,则返回空响应。这种方式比 fetch 拦截器更可靠,因为它能覆盖所有来源的请求,包括 CSS 中的 @font-face。

// service-worker.js
self.addEventListener('fetch', event => {
const url = new URL(event.request.url);
if (url.pathname.endsWith('.woff2') && isFontCancelled()) {
event.respondWith(new Response('', { status: 204 }));
}
});
function isFontCancelled() {
// 从全局状态或缓存中获取取消标志
return globalThis.fontCancellationFlag;
}
在 Service Worker 中,isFontCancelled() 同样需要根据业务逻辑实现。例如,当用户离开页面或触发特定操作时,设置 globalThis.fontCancellationFlag = true,随后所有字体请求将被拦截。需要注意的是,Service Worker 需要在 HTTPS 环境下运行,并且用户需手动安装或自动激活。
基于 @font-face 声明的具体取消条件
当使用 @font-face 声明字体时,浏览器会自动发起请求,无法直接通过 JavaScript 取消。但可以通过动态移除 @font-face 规则来间接实现取消效果。例如,在 DOM 中查找包含字体规则的 标签,并将其删除,从而阻止后续请求。
function removeFontRule(fontName) {
const styles = document.querySelectorAll('style');
styles.forEach(style => {
const cssText = style.textContent;
if (cssText.includes(`@font-face { font-family: '${fontName}'`)) {
style.remove();
}
});
}
上述代码遍历所有 标签,查找包含指定字体名称的 @font-face 规则,并移除对应的标签。此方法适用于字体规则内联在 HTML 中的场景,若字体规则来自外部 CSS 文件,则需结合拦截器使用。移除规则后,浏览器将不再发起新的字体请求,但已下载的字体仍会保留在缓存中。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











