2012-07-25 56 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