Marc-François
Marc-François

Reputation: 4060

Application always returns a 304 response when the browser asks for a CSS file

I am playing a bit with Play! 2.0.2.

My project is new and the only things I changed are the HTML in the views/ directory and the main.css file in the public/ directory.

The problem is that even when I make a modification to the CSS file, the application still responds with a 304 Not Modified. Ctrl+R and F5 don't fix the problem. The only way to really refresh the page is to go into the browser's settings and clear the cache. Then the CSS will update, but for the next request only.

Play! seems to consider every file the public/ directory as unchanged even when it's not the case.

Do you have any idea how to fix this?

Upvotes: 0

Views: 1414

Answers (2)

Somatik
Somatik

Reputation: 4743

According to: http://www.playframework.com/documentation/2.1.0/Assets

Etag support The Assets controller automatically manages ETag HTTP Headers. The ETag value is generated from the resource name and the file’s last modification date. (If the resource file is embedded into a file, the JAR file’s last modification date is used.)

When a web browser makes a request specifying this Etag, the server can respond with 304 NotModified.

Somehow this is not working for css files (at least with play java 2.1 in development mode)

manually setting the cache timeout might be a temporary solution

"assets.cache./public/stylesheets/main.css"="max-age=1"

Upvotes: 0

biesior
biesior

Reputation: 55798

That's rather proper situation, that CSS files are not downloaded after each page refresh from the server.

Find keyboard combination in your browser for reloading the page with cache refreshing for development cycle (typically it's Shift + F5 orShift + Ctrl +R).

The other problem is how to tell 1 million of your users to press the combination after changes to the live site: the easiest way is just addiing an unique string to the CSS/JS filenames:

<link rel="stylesheet" href="/assets/css/main/css?12345" />

You can do that on many ways,

  • First just add this manually and after important changes in the CSS/JS change also ?12345 to ?34567 for all files

    <link rel="stylesheet" href='@routes.Assets.at("css/main.css")?12345'>
    
  • Second - semi-automatic: use some controller's method for generating timestamp

    <link href='@routes.Assets.at("css/main.css")[email protected]()' rel="stylesheet">
    <script src='@routes.Assets.at("js/scripts.js"[email protected]())' type="text/javascript"></script>
    
  • And create timestamp() method in Application.java

    public static String timestamp(){
        // here you can add some more control
        // but DON'T set new timestamp each time, 
        // cause you'll make the browser's cache useless
        return "12345";
    }
    
  • Third solution would be the best option for future live site: use Application.timestamp() to set custom timestamp for each file. In such case you could change/reset them when required without need to recompile the app and sending jars back to the server. Of course in this scenario you shouldn't keep the CSS files in the Play's public folder, instead it's better to use frontend HTTP server for serving them from some FTP location and use Play's database for storing paths only.

Upvotes: 3

Related Questions