Closed
Bug 1302119
Opened 8 years ago
Closed 8 years ago
fetch() does not respect cache-control headers
Categories
(Core :: Networking: Cache, defect)
Tracking
()
RESOLVED
DUPLICATE
of bug 428916
People
(Reporter: mjs, Unassigned, NeedInfo)
Details
Attachments
(1 file)
164.95 KB,
image/png
|
Details |
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:48.0) Gecko/20100101 Firefox/48.0 Build ID: 20160817112116 Steps to reproduce: Firefox seems to ignore cache-control headers passed to fetch(). As an example: 1. Load https://www.mozilla.org/en-US/. 2. Attempt to retrieve "/en-US/" over the network (avoiding cache) via: fetch(new Request("/en-US/", { headers: { "cache-control": "no-cache" }})).then(r => console.log(r)); Actual results: The path /en-US/ is retrieved from the cache. Expected results: A new network request is issued for "/en-US/". (Which is how Chrome behaves.) (I am aware that Firefox supports the cache: no-cache option, which in this case accomplishes the same thing, however I think it should respect the cache-control header as well.)
Comment 1•8 years ago
|
||
reproducible Version 48.0.1 Build ID 20160817112116 User Agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:48.0) Gecko/20100101 Firefox/48.0
Status: UNCONFIRMED → NEW
Component: Untriaged → Networking: Cache
Ever confirmed: true
Product: Firefox → Core
Comment 2•8 years ago
|
||
The server for `https://www.mozilla.org/en-US/` does not provide either of these headers: Last-Modified: Etag: Because of this the browser cannot send either the If-Modified-Since or If-None-Match none matched headers. As a result the server cannot revalidate the resource. (The 'no-cache' header value means to revalidate.) So the server just returns the complete file. If you do the same thing on a site that does support revalidation then it works correctly. For example, go open `http://example.com` in a new tab. Then execute these statements: fetch(new Request("/", { headers: { "cache-control": "default" }})).then(r => console.log(r)); fetch(new Request("/", { headers: { "cache-control": "no-cache" }})).then(r => console.log(r)); fetch(new Request("/", { headers: { "cache-control": "no-store" }})).then(r => console.log(r)); In the network monitor you should see: * A cached 200 load (since you just navigated to the site) * A 304 because the no-cache requests revalidation and nothing changed * A full network 200 load because no-store says to bypass the cache Does this work for you?
Flags: needinfo?(mjs)
Comment 3•8 years ago
|
||
feel free to reopen if this isn't resolved in firefox 49 but I'm pretty sure its a dup of a fixed issue
Status: NEW → RESOLVED
Closed: 8 years ago
Resolution: --- → DUPLICATE
Reporter | ||
Comment 4•8 years ago
|
||
bkelly: Sorry, I didn't quite follow your comment. I was not expecting requests with "cache-control: no-cache" to ever be fulfilled by the cache, as per https://tools.ietf.org/html/rfc7234#section-5.2.1.4 Chrome and Safari Preview seem to revalidate in this situation however Firefox does not. (Also verified by running a server on localhost.) > A 304 because the no-cache requests revalidation and nothing changed I was expecting a 200 in this situation. > A full network 200 load because no-store says to bypass the cache This is separate to this bug, but my reading of https://tools.ietf.org/html/rfc7234#section-5.2.1.5 is that a cached response could actually be used in this situation (see the final paragraph) and both Chrome and Safari do appear to use a cached response in this situation. (Keeping this bug resolved as a dupe of bug 428916 seems fine, though.)
Comment 5•8 years ago
|
||
> I was not expecting requests with "cache-control: no-cache" to ever be > fulfilled by the cache, as per > > https://tools.ietf.org/html/rfc7234#section-5.2.1.4 That states: " The "no-cache" request directive indicates that a cache MUST NOT use a stored response to satisfy the request without successful validation on the origin server." The part about "without successful validation on the origin server" is satisfied by a 304 response. In that case the browser can use the cached version. > Chrome and Safari Preview seem to revalidate in this situation however > Firefox does not. (Also verified by running a server on localhost.) Do these browsers send a If-Modified-Since or If-None-Match header? If so, where are they getting the value? It's possible they are setting If-Modified-Since based on when they cached it, but this is dangerous since the client clock may not match the server clock > > A 304 because the no-cache requests revalidation and nothing changed > > I was expecting a 200 in this situation. No, sine we have a Last-Modified header on the cached resource we can send an If-Modified-Since to revalidate. This results in a 304 indicating no change. > > A full network 200 load because no-store says to bypass the cache > > This is separate to this bug, but my reading of > https://tools.ietf.org/html/rfc7234#section-5.2.1.5 is that a cached > response could actually be used in this situation (see the final paragraph) > and both Chrome and Safari do appear to use a cached response in this > situation. I agree the RFC allows it, but it doesn't appear to require it. Our implementation more closely matches the fetch spec's definition of no-show: https://fetch.spec.whatwg.org/#concept-request-cache-mode
Reporter | ||
Comment 6•8 years ago
|
||
> > > A 304 because the no-cache requests revalidation and nothing changed
> > I was expecting a 200 in this situation.
> No, sine we have a Last-Modified header on the cached resource we can send an If-Modified-Since to revalidate. This results in a 304 indicating no change.
By "send an If-Modified-Since to revalidate" do you mean a network request? Provided the cached response satisfies max-age and other constraints, Firefox doesn't appear to send anything to the server in the "cache-control: no-cache" situation, conditional or not--it just used the cached response.
I also don't see any 304s in the Network panel, only cached and uncached 200s. (See attachment. The "/" resource had a max-age of 60s, and the third request was issued after 60s, so it went through to the origin, resulting in an uncached 200.)
I understood the "successful validation on the origin server" condition of 5.2.1.5 to mean that the client could only use a cached response if it issued a network request to the origin, and the origin returned a 304. Otherwise is there even any difference between no-cache and no cache-control directive?
Reporter | ||
Comment 7•8 years ago
|
||
Comment 8•8 years ago
|
||
Try in FF49+ where bug 428916 is fixed.
Reporter | ||
Comment 9•8 years ago
|
||
bkelly: it works as I was expecting it to in Firefox Nightly, thanks!
Comment 10•8 years ago
|
||
Great! FF49 should be released next week, so not long to wait.
You need to log in
before you can comment on or make changes to this bug.
Description
•