You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JS脚本检测新旧缓存文件(含图片)及强制不缓存图片?

实现客户端缓存与服务器资源的差异校验及更新提示

Absolutely, this cache validation feature is totally doable—and way more efficient than trying to force no caching for every single file, which makes sense given your large number of assets. Here's a practical, scalable approach to pull this off:

Core Idea

Instead of comparing file contents directly (which is resource-heavy), we'll use content hashes or version identifiers for your static assets. The server maintains a manifest file listing every asset and its corresponding hash. The client fetches this manifest, compares it against a locally stored copy, and triggers an update if mismatches are found.

Step-by-Step Implementation

1. Generate an Asset Manifest on the Server

First, you need a way to create a manifest file that maps each asset to its unique hash (based on file content):

  • If you're using a build tool like Webpack, Vite, or Rollup, this is built-in. For example, Webpack can generate an asset-manifest.json that looks like this:
    {
      "css/main.css": "css/main.abc123.css",
      "images/header.jpg": "images/header.def456.jpg",
      "js/app.js": "js/app.ghi789.js"
    }
    
  • If you don't use a build tool, write a simple server-side script (Node.js, Python, etc.) to iterate over your static files, calculate an MD5/SHA hash for each, and generate this JSON file.

Critical Note: Make sure this manifest file is not cached by the browser. Set its Cache-Control header to no-cache or append a query parameter (like /asset-manifest.json?v=1) to force fresh requests every time.

2. Client-Side Validation Script

Add this script to your main HTML file to check for updates on page load (and optionally, during route changes for SPAs):

First, add a notification element to your HTML (hidden by default):

<div id="update-alert" style="display: none; position: fixed; top: 0; width: 100%; background: #f8e71c; padding: 1rem; text-align: center; z-index: 9999;">
  New content is available! <button id="refresh-page">Refresh Now</button>
</div>

Then the JavaScript logic:

const MANIFEST_PATH = '/asset-manifest.json';

async function checkAssetUpdates() {
  try {
    // Fetch the latest manifest, bypassing cache
    const response = await fetch(MANIFEST_PATH, { cache: 'no-cache' });
    const latestManifest = await response.json();
    
    // Get the locally stored manifest (if exists)
    const savedManifest = JSON.parse(localStorage.getItem('assetManifest')) || {};
    
    // First load? Save the manifest and exit
    if (!Object.keys(savedManifest).length) {
      localStorage.setItem('assetManifest', JSON.stringify(latestManifest));
      return;
    }
    
    // Compare manifests for changes
    let hasUpdates = false;
    for (const [assetPath, hashedName] of Object.entries(latestManifest)) {
      if (savedManifest[assetPath] !== hashedName) {
        hasUpdates = true;
        break;
      }
    }
    
    if (hasUpdates) {
      // Option 1: Auto-refresh after a short delay (uncomment to use)
      // setTimeout(() => {
      //   window.location.reload(true); // Force reload from server
      // }, 2000);
      
      // Option 2: Show a user-facing alert with refresh button
      const alertElement = document.getElementById('update-alert');
      alertElement.style.display = 'block';
      
      document.getElementById('refresh-page').addEventListener('click', () => {
        // Update local manifest before refreshing to avoid repeated alerts
        localStorage.setItem('assetManifest', JSON.stringify(latestManifest));
        window.location.reload(true);
      });
    }
  } catch (err) {
    console.error('Failed to check for asset updates:', err);
  }
}

// Run check when the page finishes loading
window.addEventListener('load', checkAssetUpdates);

// For SPAs: Run check on route change (adjust based on your router)
// Example for React Router:
// import { useLocation } from 'react-router-dom';
// useEffect(() => { checkAssetUpdates(); }, [useLocation().pathname]);

Why This Works Better Than Forcing No Cache

  • Efficient: Only re-downloads assets that actually changed, saving bandwidth and load time.
  • User-Friendly: Either auto-refresh (with a delay) or let users choose when to refresh, instead of breaking their flow with constant re-loads.
  • Scalable: Works for any number of assets, since the manifest handles all comparisons in one place.

Additional Tips

  • If your assets are served from a CDN, make sure the hashed filenames are configured to cache indefinitely (since the hash changes only when content does).
  • For critical updates, you can tweak the script to show a more prominent alert or even block user interactions until they refresh.

内容的提问来源于stack exchange,提问作者Alex Bntz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:58:23