首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Filter 防靜態資源緩存實戰:給 JS/CSS URL 自動加時間戳,開發調試零煩惱

     編輯:Java 綜合教學

Filter 防靜態資源緩存實戰:給 JS/CSS URL 自動加時間戳,開發調試零煩惱

開發階段頻繁修改 JS/CSS,瀏覽器強緩存導致「明明改了代碼頁面卻不生效」是常見痛點。本文提供一個通用 Filter 方案:攔截 `.js`/`.css` 請求,自動在 URL 追加時間戳參數(`__oawx_t=timestamp`),強制瀏覽器重新獲取最新資源,無需手動清理緩存或修改 HTML 引用。

一、核心 Filter 實現

public class StaticResourceCacheFilter implements Filter {

    private static final Logger log = LoggerFactory.getLogger(StaticResourceCacheFilter.class);
    private static final String STATIC_TAIL = "__oawx_t=";

    @Override
    public void init(FilterConfig filterConfig) { }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        String requestURL = req.getRequestURL().toString();
        String queryStr = req.getQueryString();

        // 僅攔截 .js / .css 靜態資源
        if (requestURL != null && (requestURL.endsWith(".js") || requestURL.endsWith(".css"))) {

            String newURL = null;

            // 情況 1:已有查詢參數,且無時間戳參數 → 追加 &__oawx_t=timestamp
            if (StringUtils.isNotBlank(queryStr) && !queryStr.contains(STATIC_TAIL)) {
                newURL = requestURL + "?" + queryStr + "&" + STATIC_TAIL + System.currentTimeMillis();
            }
            // 情況 2:無查詢參數 → 直接加 ?__oawx_t=timestamp
            else if (StringUtils.isBlank(queryStr)) {
                newURL = requestURL + "?" + STATIC_TAIL + System.currentTimeMillis();
            }

            // 需要重定向時執行 302 跳轉
            if (newURL != null) {
                resp.sendRedirect(newURL);
                return;  // 終止後續 Filter 鏈
            }
        }

        // 非靜態資源或已帶時間戳,正常放行
        try {
            chain.doFilter(request, response);
        } catch (Exception e) {
            log.error("Filter chain error", e);
        }
    }

    @Override
    public void destroy() { }
}

二、配置參數常量類

public class ParameterConfig {
    /** 靜態資源防緩存時間戳參數名 */
    public static final String STATIC_TAIL = "__oawx_t=";
}

三、web.xml 註冊 Filter

<filter>
    <filter-name>staticCacheFilter</filter-name>
    <filter-class>com.yourpkg.StaticResourceCacheFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>staticCacheFilter</filter-name>
    <url-pattern>/*</url-pattern>  <!-- 攔截所有請求,Filter 內部判斷後綴 -->
</filter-mapping>

四、效果演示

原請求:GET /static/app.js?v=1.0
重定向後:GET /static/app.js?v=1.0&__oawx_t=1705574400123

瀏覽器 Network 面板顯示 302 重定向並帶上時間戳參數

五、原理與優缺點分析

維度說明
原理URL 變化 → 瀏覽器視為新資源 → 繞過強緩存(Cache-Control: max-age)直接向伺服器請求
優點零侵入業務代碼、無需修改 JSP/HTML 引用、開發環境自動生效、生產可關閉 Filter
缺點每次請求觸發 302 重定向,增加一次網路往返;生產環境必須關閉,否則影響緩存效能
適用場景開發/測試環境;生產環境請改用構建工具(Webpack/Vite)生成內容哈希文件名(如 app.a1b2c3.js)

六、生產環境最佳實踐對比

方案環境原理維護成本
Filter + 時間戳開發/測試URL 參數變化零配置,自動生效
構建工具 Hash 文件名生產文件名含內容哈希(app.[hash].js)需構建流程支援,長期有效
Nginx add_header Cache-Control no-cache開發/特定目錄響應頭禁用緩存需運維配置,影響所有資源
HTML ``頁面級頁面元標籤僅影響 HTML 文檔本身,不影響 JS/CSS
提醒:上線前務必在 web.xml 註釋掉該 Filter,或通過 Spring Profile 僅在 dev 環境啟用,避免生產環境緩存失效導致流量暴增。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved