以下是配置浏览器自动本地缓存图片的JavaScript实现方案,使用 Service Worker 和 Cache API 实现资源缓存,提升网页加载速度和离线访问能力:


一、基础配置步骤

1. 注册 Service Worker

在网页主文件(如 index.html)中添加以下代码:

html
复制
<script>// 检查浏览器是否支持 Service Worker
if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/sw.js')
      .then(registration => {
        console.log('ServiceWorker 注册成功:', registration.scope);
      })
      .catch(err => {
        console.log('ServiceWorker 注册失败:', err);
      });
  });
}</script>

2. 创建 Service Worker 脚本(sw.js

javascript
复制
// 定义缓存名称和版本const CACHE_NAME = 'image-cache-v1';const IMAGE_REGEX = /\.(png|jpe?g|webp|gif|svg)$/i;// 安装阶段:预缓存关键资源(可选)self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(cache => {
        return cache.addAll([
          '/default-image.jpg', // 预缓存默认图片
        ]);
      })
  );});// 拦截请求并缓存图片self.addEventListener('fetch', (event) => {
  const url = event.request.url;

  // 仅处理图片请求
  if (IMAGE_REGEX.test(url)) {
    event.respondWith(
      caches.match(event.request)
        .then(cachedResponse => {
          // 返回缓存内容,若不存在则请求并缓存
          return cachedResponse || fetch(event.request)
            .then(response => {
              // 克隆响应以存入缓存
              const responseClone = response.clone();
              caches.open(CACHE_NAME)
                .then(cache => {
                  cache.put(event.request, responseClone);
                });
              return response;
            });
        })
    );
  } else {
    // 非图片请求直接通过
    return event.respondWith(fetch(event.request));
  }});// 清理旧缓存self.addEventListener('activate', (event) => {
  event.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.map(cache => {
          if (cache !== CACHE_NAME) {
            return caches.delete(cache);
          }
        })
      );
    })
  );});

二、高级优化配置

1. 控制缓存策略

javascript
复制
// 在 fetch 事件中添加缓存有效期控制const MAX_AGE = 86400 * 7; // 缓存7天event.respondWith(
  caches.match(event.request)
    .then(cachedResponse => {
      const fetchPromise = fetch(event.request)
        .then(response => {
          if (response.status === 200) {
            const headers = new Headers(response.headers);
            headers.set('sw-cache-date', new Date().getTime());
            const modifiedResponse = new Response(response.body, {
              status: response.status,
              statusText: response.statusText,
              headers: headers            });
            caches.open(CACHE_NAME)
              .then(cache => cache.put(event.request, modifiedResponse));
          }
          return response.clone();
        });

      // 检查缓存是否过期
      if (cachedResponse) {
        const cacheDate = new Date(parseInt(cachedResponse.headers.get('sw-cache-date'))).getTime();
        if ((Date.now() - cacheDate) / 1000 < MAX_AGE) {
          return cachedResponse;
        }
      }
      return fetchPromise;
    }));

2. 处理缓存存储限制

javascript
复制
// 在缓存时检查存储配额navigator.storage.estimate()
  .then(estimate => {
    const used = estimate.usage;
    const quota = estimate.quota;
    if (used / quota > 0.9) {
      console.log('存储空间不足,清理旧缓存...');
      caches.open(CACHE_NAME)
        .then(cache => {
          cache.keys()
            .then(keys => {
              if (keys.length > 50) {
                cache.delete(keys[0]);
              }
            });
        });
    }
  });

3. 跨域图片缓存处理

确保服务器设置 CORS 头:

http
复制
Access-Control-Allow-Origin: *Access-Control-Allow-Methods: GET

在请求中指定模式:

javascript
复制
fetch(event.request, { mode: 'cors' });

三、使用示例

  1. 首次加载:图片从网络请求并存入缓存;

  2. 再次访问:优先从缓存加载图片;

  3. 离线状态:展示已缓存的图片。


四、注意事项

  1. HTTPS 要求:Service Worker 仅在 HTTPS 或 localhost 环境下生效;

  2. 缓存更新:修改 CACHE_NAME 版本号触发缓存更新;

  3. 存储限制:不同浏览器对缓存容量限制不同(通常为域名的50%-80%磁盘空间);

  4. 用户隐私:需在隐私政策中说明缓存行为。


通过以上配置,用户访问网页时图片将自动缓存至本地,显著提升二次加载速度和离线可用性。可根据实际需求调整缓存策略(如LRU清理、动态缓存规则等)。

本篇文章内容来源于:配置浏览器自动本地缓存图片的JavaScript实现方案