2012-07-25 126 views
0

當我需要處理Spring MVC上的自定義響應數據類型時,似乎有些尷尬。強制瀏覽器緩存來自Spring MVC的JS響應

在我的情況下,我需要返回一個JavaScript內容。但是,我希望它是緩存。

因此要澄清,這不是一個靜態文件大小寫(<mvc:resources...),而是它是服務器上生成的一個動態文件,我確實想要緩存(即HttpResponse 200和HttpResponse 302)。

在代碼方面,在客戶端我只是有:

<script src="<spring:url value='/some-file.js'/>"></script> 

比一個用SpringMVC控制器:

@RequestMapping(value = "/some-file.js") 
public ResponseEntity<String> resourceBundles(HttpServletRequest request, HttpServletResponse response, Locale locale) throws IOException { 

    responseHeaders.add("Cache-Control", "public, max-age"); 
    responseHeaders.add("Content-Type", "text/javascript; charset=UTF-8"); 
    responseHeaders.add("Expires", "max-age"); 

    // Turn this into JSON response: 
    String someJson = "{ a:a, b;b};"; 
    return new ResponseEntity<String>("var data = " + someJson, responseHeaders, HttpStatus.OK); 
} 

但是,它似乎是瀏覽器總是試圖訪問此動態JS文件。

由於此文件是依賴於Session的,因此無法生成該文件並將其視爲靜態文件。

有什麼建議嗎?

+0

這可能是有用的:http://stackoverflow.com/questions/1362930/how-do -you-set-cache-headers-in-spring-mvc – beny23 2012-07-25 09:43:31

回答

0

這是正確的行爲。大多數瀏覽器會通過If-Modified-Since +時間戳向您發送GET請求,以檢查文件是否已更改。

在通常情況下,您將使用時間戳記來確定文件是否已更改。但由於它在你的情況下從不改變,你可以用304/HttpStatus.NOT_MODIFIED response without a response body(而不是200/OK)回覆。

告訴瀏覽器文件沒有改變。

這應該工作:

@RequestMapping(value = "/some-file.js") 
public ResponseEntity<String> resourceBundles(
    HttpServletRequest request, 
    HttpServletResponse response, Locale locale) throws IOException { 

    Date lmod = session.getAttribute("lmod"); 
    if(null == lmod) { 
     lmod = new Date(); 
     session.setAttribute("lmod", lmod); 
    } 

    responseHeaders.add("Last-Modified", lmod); 

    String ifModifiedSince = request.getHeader("If-Modified-Since"); 
    if(null != ifModifiedSince) { // You may want to compare lmod and ifModifiedSince here, too 
     return new ResponseEntity(responseHeaders, HttpStatus.NOT_MODIFIED); 
    } 

    ... create first time response ... 
} 

告訴瀏覽器Last-Modified將使它能夠向您發送If-Modified-Since

+0

謝謝。這個邏輯對我來說很清楚,但我不清楚如何基於客戶端的請求創建一個機制來回復200或304。在chrome中測試它,我沒有看到If-Modified-Sinse被髮送。 – 2012-07-25 12:09:24

+0

我編輯了我的答案。 – 2012-07-25 13:13:07

+0

感謝您的努力。這或多或少是我所嘗試的,但是是修飾的,因爲在任何情況下都是空的。我測試了它與所有瀏覽器看到類似的行爲。使用chrome,我可以清楚地看到這個「Dynamic」JS不會發送這個頭文件,而位於mvc:resources路徑中的其他JS會發送If-Modified-Since。我會檢查是否可以將此路徑添加到mvc:resources組。 – 2012-07-25 13:21:09