Search code examples
node.jshttp-errornode-fetch

HTTP 200 (OK) returned instead of 301 (Moved Permanently)


This URL returns a code 301 to wget and curl, but node-fetch is reporting 200:

# wget https://www.h24info.ma/feed
--2021-03-19 11:30:23--  https://www.h24info.ma/feed
Resolving www.h24info.ma (www.h24info.ma)... 104.21.39.120, 172.67.145.67, 2606:4700:3030::6815:2778, ...
Connecting to www.h24info.ma (www.h24info.ma)|104.21.39.120|:443... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
# curl -I https://www.h24info.ma/feed
HTTP/2 301

But fetch returns 200 (and hangs forever) :

fetch('https://www.h24info.ma/feed', {
  'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36',
  'accept': 'text/html,application/xhtml+xml'
}).then(function (res) {

  console.error('node-fetch status: %s', res.status);
});

node-fetch status: 200

Am I missing something? Fetch should return 301 so the request can be aborted and the error dealt with.

software version
node-fetch 2.6.1
node v14.15.3
npm 7.6.0
Operating System Linux 4.9.0-15-amd64 #1 SMP Debian 4.9.258-1 (2021-03-08) x86_64 GNU/Linux

Solution

  • By default fetch follows redirects transparently. That is, if the URL requested returns a 301/302 redirect response code, fetch will automatically make another request to the redirect URL, and the response you get will be the one from that second request.

    You can configure this behaviour via the redirect field in the fetch options object:

    fetch(URL, {
      redirect: 'manual' // do not follow redirects automatically
    })
    

    Check out the MDN docs for fetch for more information.

    Fetch should return 301 so the request can be aborted and the error dealt with.

    A 301 status is not really an error, so in my opinion the default behaviour of fetch is correct. In most cases, what you want is fetch to request the resource specified, regardless of where it actually is. To that end, if a server tells fetch to look elsewhere for a resource, it will.