0

I found out that some browser (probably Safari; I'm waiting for the answer) cache my Javascript without being told to.

The script gets loaded simply by

<script src="some-name.js"></script>

The server (my embedded Jetty) sends the following headers:

Date: Fri, 03 Mar 2017 00:17:04 GMT
Server: ...
Vary: origin, accept-encoding, authorization, x-role
Date: Fri, 03 Mar 2017 00:17:04 GMT
Content-Type: application/javascript; charset=utf-8
Content-Encoding: gzip
ETag: "0e5dd67b500a018f0996bc417e032083"

The ETag computations seems to be right. The Date is repeated twice (no idea why), but IMHO no date matters at all, as there's no expiration. I expect the browser to send If-None-Match:"0e5..." whenever the page is needed, am I wrong?

As I'm using HTTPS exclusively, so I don't care about proxy caches. I see that loading all files individually and always checking their freshness is very inefficient, but that's another story. So I thought, I'd need no cache control for now.

For now I wonder if a browser is allowed to cache a page (and for how long) without an explicit permission and without checking its freshness? How can I disable it? (*)


(*) I do want caching, but only after checking the ETag.

7
  • 1
    ETag is also part of HTTP caching. You often have to explicitly tell browsers to not cache via e.g. Cache-control: no-cache Commented Mar 3, 2017 at 0:44
  • 1
    Expanding on @LukeBriggs 's comment, you need to send a cache control header from the server that is serving up the js files. This will tell the browsers how/if/when to cache your file and when to renew. It's not a client side thing. developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control Commented Mar 3, 2017 at 0:57
  • @LukeBriggs Sure, ETag is for caching and that's what I want. no-cache is obviously wrong. Commented Mar 3, 2017 at 1:00
  • @maaartinus what makes you say no-cache is obviously wrong? It's written in the specifications that when it's honoured (which is true for all major browsers) it'll make sure a response is not cached. Commented Mar 3, 2017 at 1:08
  • 1
    @LukeBriggs Apologies, I can see I was pretty unclear! Edited. Commented Mar 3, 2017 at 1:35

1 Answer 1

1

ETag causes caching

When an entity tag is present it increases the responses 'cacheability'. Simply omitting ETag leaves caching behaviour undefined - it may or may not be cached:

Unless specifically constrained by a cache-control (section 14.9) directive, a caching system MAY always store a successful response

As a side note here, browsers agressively cache things - as seen above, the specification allows them to cache responses unless explicitly told not to, so they do.

So, if you want to make sure something doesn't cache, use the Cache-Control header:

Cache-control:no-cache 

Adding this header will prevent the browser from caching. It overrides any of the other caching rules, such as Last-Modified, Expires, ETag etc:

If the no-cache directive does not specify a field-name, then a cache MUST NOT use the response to satisfy a subsequent request without successful revalidation with the origin server.

In practice this means a browser won't store anything.

If you want to force something to revalidate every time add max-age=0:

Cache-Control: max-age=0

The request includes a "max-age=0" cache-control directive, which forces each cache along the path to the origin server to revalidate its own entry

The difference here is that the browser will store the file and revalidate every time the resource is used, i.e. send the ETag to the origin server and (hopefully) get a 304 not modified response.

This has similar behaviour to must-revalidate, which requires a revalidation everytime too, although the difference with that it is must not serve a stale response. It's required to respond with 504 if it can't contact the origin (whereas max-age=0 can serve the stale response even if no contact is possible).

Summary

Don't store anything:

Cache-Control: no-cache

Store, but check every time. If we can't check (no internet), use the cached one:

Cache-Control: max-age=0

Store, but check when it expires. If we can't check (no internet), fail:

Cache-Control: must-revalidate
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.