fetch拦截器必须在页面最早期注入,否则失效;需置于最前中,加防重标记,禁用DOMContentLoaded,匹配URL路径而非destination,重定向需构造新fetch请求并注意credentials与body复用,离线fallback须前后端缓存命名与路径严格一致。

fetch 拦截器必须在页面最早期注入,否则失效
HTML 本身不提供任何拦截能力,所谓“拦截静态资源”,本质是用 JavaScript 劫持 window.fetch。如果脚本执行晚于其他模块(比如 React/Vue 已初始化、第三方 SDK 已调用过 fetch),原始 fetch 就可能已被缓存或封装,再代理就无效。
必须把拦截逻辑写在 里最靠前的 <script></script> 中,且加防重机制:
- 检查
window.__fetchProxied标记,避免重复代理 - 不要用
document.addEventListener('DOMContentLoaded')—— 太晚,很多资源请求已发出 - 若用构建工具(如 Vite),确保该脚本被标记为
type="module"或设defer,但绝不async
匹配静态资源不能只看 request.destination
request.destination 在 preload、fetch() 显式调用、CORS 场景下极不可靠:字体在 Chrome 返回 font,Firefox 可能是 style;fetch('/api/config.json', {mode: 'no-cors'}) 会让 destination 变成 empty。
真正稳定的方式是正则匹配 URL 路径:
把任意文章或文档内容转换成精美的全屏翻页 HTML 演示文件(幻灯片风格)。当用户发来一篇文章、文档链接、Markdown 内容、或粘贴的文本,并且希望生成演示用的 HTML 时触发。支持任意内容来源:iWiki 链接、KM 链接、本地文件路径、直接粘贴的文本。生成的 HTML 文件保存到本地工作区,并通过企微直接发送给用户。触发词示例:帮我把这篇文章做成PPT、转成演示文档、生成HTML幻灯片、做个演示、转成可以演示的格式、article to deck、make a slide。
- 用
/\.(js|css|png|jpg|woff2?|svg|ico|webp)$/i.test(request.url) - 排除带敏感参数的请求:
/(auth=|session=|token=)/.test(request.url) - 跳过非 GET 请求:
!['GET', 'HEAD'].includes(options?.method || 'GET')
重定向到模拟 CDN 需手动构造新 URL,不能直接改 request
Request 实例是只读的,无法修改其 url 或 headers。想“重定向”,只能在拦截器中 return fetch(newUrl, options),但要注意:
- 原
request的 body 是 ReadableStream,只能读一次,必须先await request.clone().arrayBuffer()再传给新请求 - 模拟 CDN 域名要统一,比如把
https://example.com/static/app.js→https://cdn.mock.dev/static/app.js - 保持查询参数不变:
new URL(request.url).search要拼接到新 URL 后 - 若原请求带
credentials: 'include',新请求也必须带上,否则跨域失败
离线时 fallback 到本地镜像需配合 Service Worker
纯前端 fetch 拦截器无法访问 Cache API,也就没法读取 caches.match()。想实现“在线走模拟 CDN,离线走本地镜像”,必须分两层:
- 前端拦截器负责在线时 URL 重写(指向 CDN)
- Service Worker 的
fetch事件负责离线兜底:用caches.match(request)查预缓存的资源,命中则返回,未命中才 fallback 到自定义离线页 - 两者缓存命名要一致,比如都用
static-v2.3.1,且预缓存路径必须与拦截后发出的 URL 完全一致(含协议、域名、尾斜杠、查询参数)
最容易被忽略的是:Service Worker 的 install 阶段预缓存列表,必须和前端拦截器最终发出的 URL 字符串一模一样——差一个大小写或 ?v=2.3.1 就匹配失败,离线时直接 404。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










