Differences between fetch() and env.ASSETS.fetch()
Is there any documentation on the differences between these two functions? I'm migrating a site from Workers to Pages (with functions), and I'm seeing test failures that I tracked down to subtle differences between how these two methods handle
ETag
headers.
For example, it looks like fetch()
will strip ETag
headers by default, whereas env.ASSETS.fetch()
will not. It's easy enough for me to remove the ETag
header myself, but I'm concerned that there are other behavior differences that I might not be aware of.11 Replies
I also just noticed that responses served from Pages functions do not contain the
Cf-Cache-Status
header, whereas responses served from my old Worker file did.
That header was useful to determine my cache hit ratio. Is there a configuration option I can set to add that header back?https://developers.cloudflare.com/workers/runtime-apis/bindings/service-bindings/ https://developers.cloudflare.com/workers/runtime-apis/fetch/
Cloudflare Docs
Service bindings - Runtime APIs · Cloudflare Workers docs
Facilitate Worker-to-Worker communication.
Cloudflare Docs
Fetch · Cloudflare Workers docs
An interface for asynchronously fetching resources via HTTP requests inside of a Worker.
Thanks for the links @cocosrobal but those resources don't cover the differences between the two
fetch()
methods, nor do they explain why env.ASSETS.fetch()
would have different behavior when it comes to ETag
and Cf-Cache-Status
headers.Here's an example of the headers I see when using
fetch()
:And then here's an example requesting the exact same resource, but using
env.ASSETS.fetch()
:Notice how the first screenshot includes the
Cf-Cache-Status
header (but no ETag
header). And the second screenshot includes the ETag
header, but no Cf-Cache-Status
header.
The first example also retains the X-Cache
X-Cache-Hits
X-Served-By
and X-Timer
headers from the origin server, whereas the second example strips those headers.fetch is https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
ASSETS.fetch is a Pages API for fetching assets. It does not fetch an origin or anything, it's just for fetching static assets
It will run through the Pages serving things so add etag, headers, handle redirects, etc.
ASSETS.fetch is a Pages API for fetching assets. It does not fetch an origin or anything, it's just for fetching static assetsThis is not quite true, as both of the screenshots I mentioned above were from assets fetched from an external origin. So both
fetch()
and env.ASSETS.fetch()
support that, they just have different behavior.
It sounds like the answer to my question is that "no" there is no documentation that explains the difference. I'd like to suggest that there should be.env.ASSETS does not fetch origins, if it does that's a problem. It runs our asset serving path which will handle everything
We don't do any external fetches in that path that I'm aware of.
from your description though it didn't sound like it hit an origin - if you have a url i can hit i can verify what's going on
Ok, I just checked with the following code:
This code doesn't error, but it looks like it actually is fetching the
/
path from the assets. (I.e. the "origin part of the URL is ignored and only the "pathname" part is used.)
I didn't notice a difference before because my external origin had the same content as my pages account.
Regarding my question about Cf-Cache-Status
is threre any way to determine whether there was a cache hit when requesting an asset via env.ASSETS.fetch()
? Ideally without manually implenting caching via the Cache API?
...or is the assumption that everything is a "cache hit" (even if it's located in another edge node) and the better thing to measure is the time it takes to fetch the response?That's correct yes, the hostname is essentially just ignored
we don't know ourselves when we get a cache hit at all times, it's something we have an open FR for
But from my own metrics, we hit cache the vast majority all the time.