How do I determine the status code of a Fetch request?

10,723

Solution 1

As far as why the code can’t just check response.status: In the case of redirects, that will be the status code of whatever response ultimately comes back as the result of any redirects.

So if redirects end up taking things somewhere that returns a 200, then response.status will just be 200. No intermediate status codes are exposed to frontend JavaScript running in a browser—as the previous (very good) answer posted here already points out.

This does give me a lot of information, especially it tells me via:

response.redirected

It’s worth noting: to just detect if there’s been a redirect, you actually don’t even need to check that. That’s the easiest way to check, but you could also just check response.url, and if that’s different from the request URL you gave to the fetch(…) call, you know it was redirected.

That used to be the typical way to check before response.redirected was first introduced.

Also worth noting: redirect: 'true' in the code in the question isn’t valid; it’ll cause the code to fail prematurely. See https://developer.mozilla.org/en-US/docs/Web/API/Request/redirect:

Value A RequestRedirect enum value, which can be one the following strings:

  • follow
  • error
  • manual

So what the code in the question seems to intend is redirect: 'follow'. But that’s actually the default for redirect, so you don’t need to explicitly specify it and can instead just omit it.

As far as the other redirect values: As explained in an answer to another question here at Stack Overflow, you almost certainly never want to specify manual except for some Service Worker cases. And error means to treat any redirect as a network error.

In that case, for the code in the example, redirect: 'true' would cause the catch to get hit and you’d have no access to any details of the response, including whether it got redirected.

So to loop back to your original question:

I want to fetch an URL and determine what status code it has, especially if it has an HTTP 301 or HTTP 302 status code

…the answer is that for redirected requests there really is no way from frontend JavaScript code running in a browser to detect the exact status codes of any redirect.

So if you need to know the exact status code for any redirects that may happen for a request to a given URL, you must make the request from backend code, and handle the response there.

Solution 2

OK first to answer your question no you cannot determine the difference between 301 and 302 without some changes in the backend.(Follow this SO dicussion for backend solution).

The other thing you can do is to set redirect to 'error' in which cases fetch will throw an error on all redirects and you can handle what happens if it was a redirect.

The main reason why this is like that is (from my understanding) is because the difference between 301 and 302 is mainly useful to browsers which needs to handle how subsequent request should behave (whether to permanently change the cache or just this request).

But in terms of the user the spec specifies both cases to handled transparently meaning you need to know there is a redirect but what status code caused the redirect does not matter. Hence only the response.redirected flag. But if you still need to please follow the above backend solution.

Share:
10,723
Franz Enzenhofer
Author by

Franz Enzenhofer

awesome and sometimes even better

Updated on July 29, 2022

Comments

  • Franz Enzenhofer
    Franz Enzenhofer almost 2 years

    I want to fetch an URL and determine what status code it has, especially if it has an HTTP 301 or HTTP 302 status code:

    fetch('https://httpstat.us/301', {
        redirect: 'true'})
        .then(response => {
           console.log(response);
           const headers = response.headers.entries();
           for (h of headers) {
            console.log(h);
            }
        }).catch(err => {
            console.log("in error case")
            console.log(err);
        })
    

    This does give me a lot of information, especially it tells me via:

    response.redirected 
    

    Which is true. But this only tells me that it redirected, not what the status code was.

    Is there a way to use Fetch API to determine the real status code of the request?