Fetch() follows redirects from origin instead of passing them to the client

Hi! I’m desperately trying to prevent my worker from following redirects by itself. My test code looks like this:

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

async function testFetch(request) {
    let modifiedRequest = new Request(request.url, {
        redirect: "manual"
    })
    
    let response = await fetch(modifiedRequest)
    
    console.log(response.status)
    console.log(response.headers.get("Location"));
    
    return response
}

Expected behavior: If request.url returns a redirect, I would assume to see either 301 or 302 printed to the console, followed by the target url of the redirect.

Actual behavior: fetch() seems to follow the redirect (even though I’m explicitly stated in the request options to NOT follow) internally and response contains whatever http status and body content the target URL responded.

If I put redirect: "follow" in the request options, I get the exact same behavior. If I put anything else there, I get the following message printed to the console: Uncaught (in response) TypeError: Invalid redirect value, must be one of "follow" or "manual" ("error" won't be implemented since it does not make sense at the edge; use "manual" and check the response status code). So apparently I did set it at least at the correct place and it should do what I want it to do.

Did I miss something? Is this a bug?

Thanks in advance

Does this happen only in the preview, or does it also happen if you deploy the worker and test against the production edge?

1 Like

Holy christ, thank you! While checking this, I’ve noticed that I completely forgot to put the correct origin hostname into the request url and just reused that which points to the worker itself. Surprisingly the request was sent to the origin (how?) and the origin did response with a redirect, but because reasons it was followed instantly. After I put the correct origin hostname into the request, the response contains the redirect itself, just as I had intended. ¯_(ツ)_/¯

1 Like

Ah, interesting … perhaps you ran into the “double worker invocation” issue with the preview service. If you have a worker that is deployed on a particular route, and preview a worker (perhaps the same one) which forwards or sends a subrequest to that route, then the worker will be invoked twice: once in the preview service, and once at the production edge.

So perhaps you had an old version without the redirect: "manual" property deployed, and that was what was following the redirects?

At any rate, glad it’s resolved!

1 Like