W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
大家好,我是 V 哥。今天咱們來(lái)聊一聊 Java 后端確保 JavaScript 不被緩存的問(wèn)題,先來(lái)了解一下為什么需要這樣做,通常源于以下幾種場(chǎng)景或問(wèn)題:
瀏覽器緩存機(jī)制是為了加快加載速度和減少服務(wù)器壓力,但有時(shí)會(huì)帶來(lái)問(wèn)題。當(dāng) JavaScript 文件更新后,如果瀏覽器從緩存中加載舊版本,用戶就無(wú)法看到最新的功能或修復(fù)的 Bug。舉個(gè)例子:開(kāi)發(fā)者發(fā)布了新版本的前端代碼,修復(fù)了一個(gè)關(guān)鍵問(wèn)題,但用戶的瀏覽器仍然使用緩存的舊代碼,導(dǎo)致問(wèn)題依然存在。用戶可能以為網(wǎng)站沒(méi)修復(fù)或出現(xiàn)新問(wèn)題,從而影響用戶體驗(yàn)。
在 Java Web 應(yīng)用中,JavaScript 通常用于與后端服務(wù)交互。如果 JavaScript 代碼版本和后端邏輯不一致,可能導(dǎo)致不兼容問(wèn)題。舉個(gè)例子:后端接口的請(qǐng)求格式發(fā)生變化,但瀏覽器仍然使用舊的 JavaScript 代碼,結(jié)果是客戶端與服務(wù)器之間通信失敗,產(chǎn)生錯(cuò)誤。
在開(kāi)發(fā)和調(diào)試環(huán)境中,緩存會(huì)導(dǎo)致代碼變更后無(wú)法即時(shí)看到效果,這對(duì)于調(diào)試過(guò)程非常不便。開(kāi)發(fā)者可能會(huì)在調(diào)試中發(fā)現(xiàn)修改的代碼沒(méi)有被應(yīng)用,導(dǎo)致浪費(fèi)時(shí)間。舉個(gè)例子:開(kāi)發(fā)者修改了 JavaScript 文件,但由于緩存,瀏覽器繼續(xù)執(zhí)行舊的代碼,開(kāi)發(fā)者無(wú)法驗(yàn)證新代碼是否正確,甚至可能以為代碼本身有問(wèn)題。
舊的緩存可能會(huì)暴露系統(tǒng)之前存在的漏洞。即使后端做了升級(jí),修復(fù)了安全漏洞,但如果瀏覽器加載了舊的 JavaScript 文件,可能仍然會(huì)受到攻擊。舉個(gè)例子:假設(shè)某個(gè)版本的 JavaScript 中存在一個(gè) XSS 漏洞。雖然新版本已經(jīng)修復(fù)了這個(gè)漏洞,但瀏覽器緩存的舊文件仍然暴露在攻擊風(fēng)險(xiǎn)中。
所以,如果前端頁(yè)面無(wú)法及時(shí)響應(yīng)更新(如修復(fù) Bug、優(yōu)化功能等),用戶體驗(yàn)可能會(huì)受到負(fù)面影響。特別是在進(jìn)行產(chǎn)品版本迭代時(shí),緩存問(wèn)題可能會(huì)使新功能看起來(lái)未上線,影響用戶的使用體驗(yàn)和滿意度。
在 Java Web 開(kāi)發(fā)中,為了確保 JavaScript 文件(或任何靜態(tài)資源)不被瀏覽器緩存,可以使用以下幾種經(jīng)驗(yàn):
為 JavaScript 文件的 URL 添加一個(gè)版本號(hào)或時(shí)間戳,使得每次文件更新后 URL 不同,這樣瀏覽器會(huì)認(rèn)為是新的資源,從而重新加載。比如:
<script src="app.js?v=1.0.1"></script>
或者使用動(dòng)態(tài)的時(shí)間戳:
<script src="app.js?t=<%= System.currentTimeMillis() %>"></script>
通過(guò)這種方式,每次生成不同的查詢參數(shù),瀏覽器會(huì)認(rèn)為這是一個(gè)新的文件,不會(huì)從緩存中讀取。
在 Java 后端(比如 Spring Boot 或 Servlet),可以通過(guò)設(shè)置 HTTP 頭來(lái)控制緩存。常見(jiàn)的 HTTP 頭包括:
Cache-Control
: 控制緩存行為。Pragma
: 控制緩存行為(主要用于兼容 HTTP/1.0)。Expires
: 設(shè)置資源過(guò)期的時(shí)間。示例代碼(Spring Boot 過(guò)濾器):
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class NoCacheFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
httpResponse.setHeader("Pragma", "no-cache");
httpResponse.setHeader("Expires", "0");
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void destroy() {}
}
在 Spring Boot 項(xiàng)目中,可以通過(guò)配置類(lèi)來(lái)定義靜態(tài)資源的緩存策略。例如:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/js/**")
.addResourceLocations("classpath:/static/js/")
.setCachePeriod(0); // 0 表示不緩存
}
}
通過(guò) setCachePeriod(0)
設(shè)置緩存周期為 0,強(qiáng)制瀏覽器每次都從服務(wù)器獲取最新的 JavaScript 文件。
ETag
或 Last-Modified
在 HTTP 響應(yīng)中設(shè)置 ETag
或 Last-Modified
,這樣瀏覽器在每次請(qǐng)求時(shí)都會(huì)詢問(wèn)服務(wù)器資源是否更新。如果沒(méi)有變化,服務(wù)器會(huì)返回 304 狀態(tài)碼,從而避免不必要的重新加載。
示例(設(shè)置 Last-Modified
):
httpResponse.setDateHeader("Last-Modified", System.currentTimeMillis());
上面的幾種方法,能確保瀏覽器及時(shí)獲取最新版本的 JavaScript 文件,不使用緩存的舊版本。
問(wèn)題來(lái)了,那什么時(shí)候可以使用緩存?
雖然緩存可能帶來(lái)這些問(wèn)題,但并不意味著緩存永遠(yuǎn)不好。在某些場(chǎng)景中,使用瀏覽器緩存可以顯著提升性能:
如何平衡?
通常,咱們不會(huì)完全禁止緩存,而是通過(guò)版本號(hào)、哈希、緩存控制頭等方式來(lái)平衡性能和更新問(wèn)題。這樣,瀏覽器在沒(méi)有必要時(shí)可以利用緩存,而在需要時(shí)也能獲取最新的資源。關(guān)注威哥愛(ài)編程,碼碼通暢不掉發(fā)
。
Java后端防止JavaScript緩存的策略Java后端
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: