80

I've recently been playing with the Javascript Fetch API. As far as I understand, by default all redirects are handled transparently and in the end I get a response from the last call in the redirect chain.

However, I could invoke fetch with {redirect: 'manual'}, in which case it would return an opaqueredirect response with no usable information. From https://fetch.spec.whatwg.org/#concept-filtered-response-opaque-redirect

An opaque-redirect filtered response is a filtered response whose type is "opaqueredirect", status is 0, status message is the empty byte sequence, header list is empty, body is null, and trailer is empty.

https://fetch.spec.whatwg.org/#http-fetch says that a response gets to be opaqueredirect if redirect is set to 'manual':

Switch on request’s redirect mode:
...
- manual
    Set response to an opaque-redirect filtered response whose internal response is actualResponse.

The specification also says:

In other words, an opaque filtered response and an opaque-redirect filtered response are nearly indistinguishable from a network error.

Given all this, why would one set redirect to manual when using the Fetch API? To me it seems pretty useless. Are there use cases where this would be useful?

3
  • 1
    Just had to use it myself. I was requesting a server that had 3 redirects, just to define some cookies. fetch was not passing those cookies, so I passed them manually. Commented Feb 23, 2018 at 14:45
  • 1
    I am using redirect: manual, to unshorten the URL Commented Jul 21, 2020 at 2:30
  • 9
    I came across the redirect property while trying to implement a log-in form using React Router. After a successful login, I want the server to return 302, but I want to handle it using client-side routing instead of issuing another request to the server. I thought the manual value is what I need, but since the opaqueredirect response doesn't contain the Location header (or any other headers, for that matter), I guess I'll have to do it some other way. I don't understand why it's implemented this way. Commented Sep 3, 2020 at 15:01

2 Answers 2

40

The short answer is: unless you’re doing something with service-worker code like what https://github.com/whatwg/fetch/issues/66 covers, you don’t ever want redirect: 'manual'.

Longer answer:

The HTML spec requires browsers to first set the redirect mode to manual when the browser starts navigating to a resource. That’s the only use in any spec for the manual redirect mode.

But because the Fetch API essentially exposes the same primitives that browsers use internally for fetches, it exposes a manual redirect mode. However, just because the API exposes a particular primitive doesn’t mean there’s a good use for that primitive in frontend code.

The spec used to require that even though you could call the API with redirect: 'manual', browsers would throw if you did — because back then nobody had yet offered any valid reason for setting it for any case other than browsers doing navigations.

But that behavior got changed due to https://github.com/whatwg/fetch/issues/66, which gives a (corner) case where redirect: 'manual' is needed in service-worker code.

A similar case of something you can set in the Fetch API but with very little utility in web-app code is mode: 'no-cors'. That was initially added just because browsers use it for certain requests, so the Fetch API exposes it. But that’s another case that has limited utility just for service workers—for caching responses to serve back as-is later without any need to examine the responses (which mode: 'no-cors' prevents web-app code from doing).

Sign up to request clarification or add additional context in comments.

3 Comments

The first paragraph is wrong. You'd need redirect: 'manual' outside of service workers too. Imagine you just want to prevent the destination endpoint to be fetched for any reason.
Yea, it's not really an answer. I have now a case where you MUST intercept redirects, because in a Digest Authentication you need to increment the nc and cnonce to follow the redirect properly.
Also in my case I'm proxying html response through backend and in such cases any frontend redirects at SSR level (using Astro) it won't update URL. If I set it to manual then browser takes care of those redirects.
1

Well, since I got this in a search result, I guess I'll answer it. The use is to prevent fetch from throwing directly, as it says, instead returning a response type of "opaqueredirect".

Retrieves an opaque-redirect filtered response when a request is met with a redirect, to allow a service worker to replay the redirect offline. The response is otherwise indistinguishable from a network error, to not violate atomic HTTP redirect handling.

-- https://fetch.spec.whatwg.org/#requests

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.