1

I've just spent an entire day on this simple worker and i've gotten no where.

I've followed the Cache API examples on the CloudFlare site and also trawled through StackOverflow postings but im still nowhere.

This post (Trouble with Cloudflares Worker Cache API) looked like it would be what I need, but it didnt help.

Essentially all im trying to do is cache certain pages for a period of time using the cache API. I will eventually need to do specific caches per country code (which is why im using workers and not page rules) but for now all im trying to do is get the basic cache API working as a test.

Here is the code, it is basically the same code from the example on their site

handler.ts

export async function handleRequest(event: FetchEvent): Promise<Response> {
  const { request } = event
  const cacheUrl = new URL(request.url)
  const cacheKey = new Request(cacheUrl.toString(), request)
  const cache = caches.default

  let response = await cache.match(cacheKey)
  if (!response) {
    console.log('NO CACHE MATCH')
    // If not in cache, get it from origin
    response = await fetch(request)
    // Must use Response constructor to inherit all of response's fields
    response = new Response(response.body, response)
    response.headers.append('Cache-Control', 's-maxage=10')
    event.waitUntil(cache.put(cacheKey, response.clone()))
  } 
  return response
}

index.ts

import { handleRequest } from './handler'

addEventListener('fetch', (event) => {
  event.respondWith(handleRequest(event))
})

I am aware that you cannot use the Cache API in the workers.dev domain so I have deployed the worker to a custom domain so it should have access to the API.

I have tried

  • Logging out the response from cache.put - nothing
  • Changing the cache key from a Response obj to a URL (string) - nothing
  • Straight await'ing the cache.put - nothing
  • Using a custom cache namespace (so await caches.open('pages')) - nothing

Basically, I just get cache misses and the request goes through to my webserver. I can see the console log, everything is running fine, it just never caches or never finds the cache.

Its incredibly hard to debug and there is next to no information returned from these methods. cache.put returns nothing, cache.match returns nothing. They might as well be mocked.

Im using wrangler to build / publish, and everything is working fine there.

Can anyone assist here?

Cheyne
  • 1,964
  • 4
  • 27
  • 43

1 Answers1

5

I think your code looks pretty straightforward / makes sense. So, to me seems like the next possibility is some sort of data issue (e.g. with the response format). Some headers, like Cache-Control and specifically Set-Cookie will affect if it can be cached - https://developers.cloudflare.com/workers/runtime-apis/cache#headers

Can you verify your response doesn't contain something that would make it uncacheable? If you are able to share the full response, or just the headers, that would also help.

David
  • 1,007
  • 7
  • 14
  • One thing I'll also add is, depending on your use case, you may be able to skip using the Cache API altogether. The `fetch` method will silently handle caching for you, if you have the proper settings in Cloudflare for the URL being requested - https://developers.cloudflare.com/workers/learning/how-the-cache-works#fetch – David Nov 08 '21 at 13:56
  • So, i think you're onto something here. I think the cache headers are preventing it from caching as I see "private no-cache" in there. However, when I try to "headers.set" to overwrite them with a a public cache control I get the error "Can't modify immutable headers". Which I dont understand because im already modifying a clone of the response as the docs state. (iv updated the original post with info) – Cheyne Nov 08 '21 at 23:07
  • 1
    Ok, I found it, and you were right it was to do with origin server cache headers being set to "no-cache" - This looks to be the standard from a NextJS SSR rendered page. Thanks a lot for your help! – Cheyne Nov 09 '21 at 00:52
  • Read your update and couple other things come to mind. Didn't notice that the cache time was set to only 10 seconds, pretty short, are you still using that? Other thing is, have you tried wrapping your handler in a try / catch already? Noticed that was different from CF's example - https://developers.cloudflare.com/workers/examples/cache-api – David Nov 09 '21 at 00:59
  • Glad you got it working! :) – David Nov 09 '21 at 01:49