Reputation: 3816
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?
Upvotes: 3
Views: 19993
Reputation: 88046
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.
Upvotes: 8
Reputation: 1079
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.
Upvotes: 4