cache.put()不能在普通html页面中调用,仅限service worker环境且须在install/activate/fetch事件中使用;需配合caches.open()、request/response对象及event.waituntil(),并辅以fetch事件监听才能生效。

cache.put() 不能直接在普通 HTML 页面里调用
你无法在 <script></script> 标签里直接写 cache.put() 并期望它生效——这个方法只在 Service Worker 环境中可用,且必须在 install、activate 或 fetch 事件回调里调用。浏览器会拒绝在主线程(即常规 HTML 页面脚本)中访问 caches 全局对象,抛出 SecurityError: caches is not defined 或类似错误。
常见误操作包括:
- 在页面
<script></script>中直接写caches.open('my-cache').then(cache => cache.put(...)) - 以为引入某个 polyfill 就能绕过限制(不行,这是硬性安全策略)
- 把 Service Worker 注册代码和缓存逻辑混写在同一 JS 文件里,却没检查
navigator.serviceWorker.ready状态
正确做法:在 Service Worker 的 install 事件中调用 cache.put()
你需要一个独立的 Service Worker 脚本(比如 sw.js),并在其中打开 Cache、构造 Response、再调用 cache.put()。关键点是:cache.put() 第一个参数必须是 Request 对象(或字符串 URL),第二个参数必须是 Response 对象——不能是普通 JSON 或字符串。
例如,想缓存一个自定义的离线页:
// sw.js
self.addEventListener('install', event => {
event.waitUntil(
caches.open('offline-cache-v1').then(cache =>
cache.put(
new Request('/offline.html'), // 注意:必须是 Request 实例或 URL 字符串
new Response('<h1>You are offline</h1>', {
headers: { 'Content-Type': 'text/html' }
})
)
)
);
});
注意:
-
new Response()的 body 必须是USVString、Blob、ArrayBuffer等可读流类型,不能是普通对象 - 如果要用 JSON 数据,得先
JSON.stringify()再传入,并设置Content-Type: application/json -
cache.put()是异步的,必须包裹在event.waitUntil()中,否则 install 可能提前结束导致缓存失败
cache.put() 写入后不会自动拦截请求,需配合 fetch 事件
仅调用 cache.put() 不会让后续网络请求命中缓存——浏览器仍会走网络。要让缓存生效,必须在 fetch 事件中主动查缓存并返回:
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
return response || fetch(event.request); // 命中则返回,否则走网络
})
);
});
常见疏漏:
- 忘了注册
fetch事件监听器,导致缓存“写进去但用不上” - 在
caches.match()前没指定缓存名,或用了和put时不一致的缓存名 - 对动态 URL(带时间戳、随机 query)不做规范化处理,导致
match失败
调试 cache.put() 是否成功:用 Chrome DevTools 的 Application → Cache Storage
刷新页面并确保 Service Worker 已激活后,在 DevTools 的 Application 标签页下展开 Cache Storage,能看到你创建的缓存名(如 offline-cache-v1),点击后可查看已存的 Request 和响应内容。如果列表为空,说明 cache.put() 没执行成功。
排查步骤:
- 检查 Console 是否有
Uncaught (in promise) TypeError: Failed to execute 'put'...类错误 - 确认 Service Worker 已安装并处于
waiting或active状态(Application → Service Workers) - 右键页面 → “Empty Cache and Hard Reload”,避免旧 SW 干扰
-
cache.put()的RequestURL 必须与页面同源,跨域 URL 需明确配置 CORS,否则可能静默失败
真正麻烦的是缓存键的匹配逻辑——Request 的 URL、method、headers(尤其是 Vary)都会影响 match 结果,而这些细节在 cache.put() 时容易被忽略。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











