Service Worker离线缓存问题:将缓存的HTML文件加载到object元素中时,内嵌图片无法加载
Service Worker离线缓存问题:将缓存的HTML文件加载到object元素中时,内嵌图片无法加载
这确实是可以实现的,问题大概率出在资源URL匹配或者Service Worker的请求处理逻辑上。我来帮你一步步排查和修复:
一、先验证缓存是否正常工作
首先咱们得确认所有需要离线访问的资源都已经被正确缓存了:
- 打开Chrome开发者工具(F12),切换到「Application」标签页
- 展开左侧的「Cache Storage」,找到你定义的
offline-cache-v6缓存 - 检查里面是否包含
/app/img.png(以及其他三个资源):- 如果图片不在缓存里,说明安装阶段缓存失败了,可能是路径写错,或者在线时资源加载失败
- 你可以在
install事件里加个错误日志,方便排查:self.addEventListener('install', event => { event.waitUntil( caches.open(CACHE_NAME) .then(cache => cache.addAll(ASSETS_TO_CACHE)) .catch(err => console.error('缓存安装失败:', err)) ); });
二、确保资源请求URL与缓存键完全匹配
这是最常见的坑:请求的URL必须和你缓存数组里的路径完全一致,包括开头的斜杠和目录结构。
比如如果你的实际文件结构是这样的:
你的网站根目录/ ├─ index.html ├─ page.html ├─ service-worker.js └─ img.png
那你之前写的/app/img.png就是错误的,应该改成/img.png(绝对路径)或者img.png(相对路径),同时更新缓存数组:
const ASSETS_TO_CACHE = [ '/index.html', '/page.html', '/service-worker.js', '/img.png' ];
并且把page.html里的图片路径改成对应的值:
<img src="/img.png" alt="Cached Image" width="300">
三、优化Service Worker的请求处理逻辑
你当前的fetch事件逻辑有两个潜在问题:
- 对
response.type !== 'basic'的判断可能会过滤掉一些合法的同源资源(虽然理论上同源请求的type都是basic,但某些场景下比如object内的请求可能会有例外) - 离线且缓存没命中时,没有 fallback 处理,直接返回网络错误
修改后的fetch事件逻辑会更健壮:
self.addEventListener('fetch', event => { // 跳过非HTTP/HTTPS的请求(比如chrome扩展的请求) if (!event.request.url.startsWith('http')) { return; } event.respondWith( caches.match(event.request) .then(cachedResponse => { // 优先返回缓存的资源,不管在线还是离线 if (cachedResponse) { return cachedResponse; } // 在线时请求网络,成功后缓存新响应 return fetch(event.request) .then(networkResponse => { // 只缓存成功的响应(状态码200-299) if (networkResponse && networkResponse.status >= 200 && networkResponse.status < 300) { const responseToCache = networkResponse.clone(); caches.open(CACHE_NAME) .then(cache => cache.put(event.request, responseToCache)); } return networkResponse; }) .catch(() => { // 离线且缓存没命中时,给图片请求返回一个占位图(可选) if (event.request.destination === 'image') { return new Response( 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzAwIiBoZWlnaHQ9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjRjNGNEY2Ii8+PHRleHQgeD0iNTAlIiB5PSI1MCUiIGZvbnQtc2l6ZT0iMTQiIGZpbGw9IndoaXRlIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LWZhbWlseT0iQXJpYWwiPkluZmluaXRhbCBJbWFnZTwvdGV4dD48L3N2Zz4=', { headers: { 'Content-Type': 'image/svg+xml' } } ); } }); }) ); });
四、更新Service Worker并验证
- 把缓存名称改成新的(比如
offline-cache-v7),这样浏览器会识别到Service Worker有更新,触发新的安装流程 - 在线打开
index.html,等待新的Service Worker注册并安装完成 - 切换到离线模式(开发者工具->Network->勾选Offline)
- 点击按钮加载
page.html,此时图片应该能正常显示了
备注:内容来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

