0

I have a cloudflare worker that will insert custom CSS into the page if the country is not U.S/Canada. This works perfectly, however - it will break all redirects when the CSS is inserted. Attached below is the worker scripts

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

async function handleRequest(request) {
    const country = request.cf.country
    if (country != 'US' && country !='CA') {
    const response = await fetch(request)
    const type = response.headers.get("Content-Type") || "";
    if (!type.startsWith("text/html")) {
     return response;
   }

    var html = await response.text()
    
    // Inject scripts
    const customScripts = 'styling here'
    html = html.replace( /<\/body>/ , customScripts)

    // return modified response
    return new Response(html, {
        headers: response.headers
    })
}
}
user77619
  • 41
  • 8

1 Answers1

1

The redirects are broken because they use a special HTTP status code (usually 301 or 302), but your Worker code is not copying the status code over to the final response, so the final response ends up always having a 200 status code.

Try changing this:

    return new Response(html, {
        headers: response.headers
    })

To this:

    return new Response(html, response)

This way, the new response copies over all of the properties of the old response, except for the body. This includes the status property, so the status code will be copied over.


By the way, unrelated to this problem, I notice another issue with your code:

if (country != 'US' && country !='CA') {

It looks like if this condition evaluates to false (that is, if country is either 'US' or 'CA'), then your handleRequest() function doesn't return a response at all. In this case, an exception will be thrown, and the client will see an 1101 error page. I recommend adding an else clause that returns the response that you want users in the US and Canada to see.

Kenton Varda
  • 41,353
  • 8
  • 121
  • 105
  • Appreciate the elaborate answer. This did fix the redirects. I tried to copy the response headers with "response.headers", and I guess I perceived this idea incorrectly – user77619 May 06 '22 at 17:52
  • As for the 1101 error warning, I do not seem to have any issue with usage. Everything is testing and working accordingly. Do you recommend still including an else clause? My actual goal here is IF NOT 'US' or 'CA' - do absolutely nothing – user77619 May 06 '22 at 17:53
  • Does "do absolutely nothing" mean "send the request to origin as if there were no worker", or does it mean "don't return a response at all"? If you want to pass through to origin, you should do `else { return fetch(request); }`. If you want to return no response, you can do something like `else { return new Response("", {status: 404}); }`. But I'm kind of confused why you aren't seeing problems currently, to be honest. – Kenton Varda May 09 '22 at 17:55
  • "do absolutely nothing" as in ignore the worker entirely. But yes, as mentioned; everything operates as intended as the code is now - hmmm - potentially default? – user77619 May 09 '22 at 21:41