简体   繁体   中英

Browser caching javascript

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.

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, ie 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM