Search code examples
javascriptcookieshttp-headerscloudflarecloudflare-workers

CloudFlare Workers - Check for Cookie, Add Headers, Set Cookie


I want to dynamically add http-headers via CloudFlare workers ONLY for the first time visitors. For example these headers:

Link: </path/to/file.css>; rel=preload; as=style; nopush
Link: </path/to/script.js>; rel=preload; as=script; nopush

So, what I need is the following, via JavaScript, in CloudFlare Workers:

  1. Check if a specific cookie exists on the client's side.
  2. If the cookie doesn't exist add http-headers and then set that specific cookie.
  3. If the cookie does exist do nothing.

You can play with the code here.

Here's a general example (involving cookie and headers) from the CF's blog:

// A Service Worker which skips cache if the request contains
// a cookie.
addEventListener('fetch', event => {
  let request = event.request
  if (request.headers.has('Cookie')) {
    // Cookie present. Add Cache-Control: no-cache.
    let newHeaders = new Headers(request.headers)
    newHeaders.set('Cache-Control', 'no-cache')
    event.respondWith(fetch(request, {headers: newHeaders}))
  }

  // Use default behavior.
  return
})

Solution

  • Here's a Cloudflare Worker that implements what you describe:

    addEventListener('fetch', event => {
      event.respondWith(handle(event.request))
    })
    
    async function handle(request) {
      // Check for cookie.
      let cookies = request.headers.get('Cookie') || ""
      if (cookies.includes("returning=true")) {
        // User has been here before. Just pass request through.
        return fetch(request)
      }
    
      // Forward request to origin, get response.
      let response = await fetch(request)
    
      // Copy Response object so that we can edit headers.
      response = new Response(response.body, response)
    
      // Add headers.
      response.headers.append("Link",
          "</path/to/file.css>; rel=preload; as=style; nopush")
      response.headers.append("Link",
          "</path/to/script.js>; rel=preload; as=script; nopush")
    
      // Set cookie so that we don't add the headers
      // next time.
      response.headers.set("Set-Cookie", "returning=true")
    
      // Return on to client.
      return response
    }