78

I'm trying to follow through on a url that redirects me to another page using the nodejs request module.

Combing through the docs I could not find anything that allows me to retrieve the url after the redirect.

My code is as follows:

var request = require("request"),
    options = {
      uri: 'http://www.someredirect.com/somepage.asp',
      timeout: 2000,
      followAllRedirects: true
    };

request( options, function(error, response, body) {

    console.log( response );

});
hitautodestruct
  • 20,081
  • 13
  • 69
  • 93

5 Answers5

87

There are two very easy ways to get hold of the last url in a chain of redirects.

var r = request(url, function (e, response) {
  r.uri
  response.request.uri
})

The uri is a object. uri.href contains the url, with query parameters, as a string.

The code comes from a comment on a github issue by request's creator: https://github.com/mikeal/request/pull/220#issuecomment-5012579

Example:

var request = require('request');
var r = request.get('http://google.com?q=foo', function (err, res, body) {
  console.log(r.uri.href);
  console.log(res.request.uri.href);

  // Mikael doesn't mention getting the uri using 'this' so maybe it's best to avoid it
  // please add a comment if you know why this might be bad
  console.log(this.uri.href);
});

This will print http://www.google.com/?q=foo three times (note that we were redirected to an address with www from one without).

Dan Abramov
  • 264,556
  • 84
  • 409
  • 511
gabrielf
  • 2,210
  • 1
  • 19
  • 11
  • 1
    You said that the above code redirects three times, how do I know which run is the last iteration? – hitautodestruct Jul 03 '13 at 11:11
  • 1
    It doesn't redirect three times. It prints the URL you were redirected to in three different ways. Sorry if that was unclear. – gabrielf Aug 19 '13 at 14:45
  • 1
    @gabrielf, No `this`, because we might use `es6`. – Gaurav Gandhi Dec 09 '16 at 04:31
  • 4
    `res.request.uri.href` will crash if the given url is bad url like 'sdfdsfdgdfgdfgdfg.sdfsdfsdf', so either you can check for `err` or presence of `res` if you want to use this option. – Sumit Jan 26 '17 at 06:49
35

To find the redirect url try this:

var url = 'http://www.google.com';
request({ url: url, followRedirect: false }, function (err, res, body) {
  console.log(res.headers.location);
});
AJcodez
  • 31,780
  • 20
  • 84
  • 118
Michael
  • 22,196
  • 33
  • 132
  • 187
6

request gets redirects by default, it can get through 10 redirects by default. You can check this in the docs. Downside of this is that you would not know if url you get is a redirected one or original one by default options.

For example:

request('http://www.google.com', function (error, response, body) {
    console.log(response.headers) 
    console.log(body) // Print the google web page.
})

gives output

> { date: 'Wed, 22 May 2013 15:11:58 GMT',
  expires: '-1',
  'cache-control': 'private, max-age=0',
  'content-type': 'text/html; charset=ISO-8859-1',
  server: 'gws',
  'x-xss-protection': '1; mode=block',
  'x-frame-options': 'SAMEORIGIN',
  'transfer-encoding': 'chunked' }

but if you give option followRedirect as false

request({url:'http://www.google.com',followRedirect :false}, function (error, response, body) {
    console.log(response.headers) 
    console.log(body)
});

it gives

> { location: 'http://www.google.co.in/',
  'cache-control': 'private',
  'content-type': 'text/html; charset=UTF-8',
  date: 'Wed, 22 May 2013 15:12:27 GMT',
  server: 'gws',
  'content-length': '221',
  'x-xss-protection': '1; mode=block',
  'x-frame-options': 'SAMEORIGIN' }
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://www.google.co.in/">here</A>.
</BODY></HTML>

So don't worry about getting the redirected content. But if you want to know if it is redirected or not set followRedirect false and check the location header in the response.

user568109
  • 47,225
  • 17
  • 99
  • 123
  • I don't understand your last sentence "If you want to know if it is redirected set `followRedirect` to `false`"? Wouldn't that stop the redirection process? – hitautodestruct May 22 '13 at 15:22
  • By default you wont get 3xx response because of automatic redirection. So if you wish to know you were redirected/don't want to redirect you must give it as false. It is just for finding out redirection. – user568109 May 22 '13 at 15:28
  • 1
    Ask yourself this, were you redirected or not (like in inception) ? you need to know what you are getting is a redirect (aka dreamworld) or direct page(or reality). It is your totem ;) – user568109 May 22 '13 at 15:38
3

If you use axios, you can fetch the redirected url like below,

 axios({
        method: 'GET',
        url: URL,
        params: {
        }
    })
        .then((response) => {
            return response.request._redirectable._options.href;
        })
        .catch(error => {
            return error;
        });
Ramkumar G
  • 41
  • 2
0

You can use the function form for followRedirect (rather than followAllRedirects), like this:

options.followRedirect = function(response) {
  var url = require('url');
  var from = response.request.href;
  var to = url.resolve(response.headers.location, response.request.href);
  return true;
};

request(options, function(error, response, body) {
  // normal code
});
Flimm
  • 136,138
  • 45
  • 251
  • 267