I have a CSS file dynamically generated by a Spring controller. I set the Cache-Control
response header in the handler method but for some reason my FireFox keeps requesting the CSS file when requesting an HTML file that has a referen开发者_Python百科ce to it instead of using the cached version.
Here's the code.
@Controller
@RequestMapping("/foo.css")
public class FooController {
@RequestMapping(method = RequestMethod.GET)
public void show(HttpServletResponse response) {
try {
response.setHeader("Cache-Control", "max-age=3600");
response.getWriter().println("this is a test.");
}
catch (IOException e) {
e.printStackTrace();
}
System.out.println(new Date());
}
}
And the HTML file references the CSS file in the usual way.
<link rel="stylesheet" type="text/css" href="/foo.css" />
What am I doing wrong here?
I'm the OP, but after further research, I've decided that you need to implement this yourself. You need to have the server generate a 304 response code for the client browser to use a cached resource, but neither Spring nor Tomcat support this out-of-box.
Well, first of all, browsers and proxy servers do not need to comply with HTTP Cache controls putted on the headers. They are only advisory. Maybe the browser is ignoring the cache request and obeying what is configured on his preferences.
Another way to do that is putting a random attribute to the url, generated by javascript. Something like:
<link type="text/css" href="/foo.css?d=328943298432" />
Here's a nice article about this subject http://code.google.com/speed/page-speed/docs/caching.html
This has been supported by Spring for quite a while now, and it has been improved in recent versions. See the reference documentation about this.
@Controller
public class FooController {
@RequestMapping("/foo.css")
public ResponseEntity<String> show() {
String cssContent = generateCssContent();
String version = hashCssContent(cssContent);
// automatically writes CacheControl + Etag headers
// generates HTTP 304 responses for conditional requests
return ResponseEntity
.ok()
.cacheControl(CacheControl.maxAge(30, TimeUnit.DAYS))
.eTag(version) // lastModified is also available
.body(cssContent);
}
}
精彩评论