0
votes

I am working on verifying 301 redirects are functioning properly. I have a Google Sheet of URLs and have a Google script that checks the status being returned:

function getStatusCode(url){
   var options = {
     'muteHttpExceptions': true,
     'followRedirects': false
   };
   var url_trimmed = url.trim();
   var response = UrlFetchApp.fetch(url_trimmed, options);
   return response.getResponseCode();
}

Next I am wanting to verify that the URL is being redirected correctly. This is where I'm getting stuck. I tried using a variation of the above code, but I can just return the URL being passed in, not the URL being redirected to, or I just get an error on my Google Sheet. Here is the last bit I tried using (that returns an error).

function getReturnedURL(url) {
   var options = {
     'method': 'GET',
     'muteHttpExceptions': true,
     'followRedirects': true
   };
   var url_trimmed = url.trim();
   var returnedUrl = ScriptApp.getService().getUrl(url_trimmed);
   var response = UrlFetchApp.fetch(returnedUrl, options);
   return response;
}

Any ideas? Or, is this even possible?

2
I cannot understand the script of ScriptApp.getService().getUrl(url_trimmed). Because getUrl() has no arguments. Ref About this line, can you explain about what you want to do? - Tanaike
@Tanaike - I was playing around with the .getUrl(); function and thought I read somewhere I could pass it in a value. The ScriptApp.getService().getUrl(); was returning null for me, so I was trying to pass it in the URL I was trying to retrieve. - Billy
Thank you for replying. I noticed that your issue was resolved. I'm glad for it. - Tanaike

2 Answers

2
votes

You cannot know what the final destination of your request is only from the HTTPresponse obtained.

However, you can use the getRedirects function below to get the URLs that your request would follow upon calling fetch with followRedirects set as true:

function getRedirects(url) {
  var params = {
    'followRedirects': false,
    'muteHttpExceptions': true
  };
  var followedUrls = [url];

  while (true) {
    var res = UrlFetchApp.fetch(url, params);
    if (res.getResponseCode() < 300 || res.getResponseCode() > 399) {
      return followedUrls;
    }
    var url = res.getHeaders()['Location'];
    followedUrls.push(url);
  }
}


function test() {
  var followedUrls = getRedirects('http://mail.google.com/mail/u/0/#inbox/');
  Logger.log(followedUrls);
}

In this case, running test will return:

[http://mail.google.com/mail/u/0/#inbox/,
https://mail.google.com/mail/u/0/,
https://accounts.google.com/ServiceLogin?service=mail&passive=true&rm=false&continue=https://mail.google.com/mail/&ss=1&scc=1&ltmpl=default&ltmplcache=2&emr=1&osid=1#]
1
votes

So for my situation, I was wanting to pull a URL from a spreadsheet and return the redirected URL in a different column of said spreadsheet. @carlesgg97 put me on the right path, here is what ended up working for me:

function urlProtocol(url){
  return URI(url).protocol()
}

function urlHostname(url){
  return URI(url).hostname()
}

function getRedirects(url) {
  eval(UrlFetchApp.fetch('https://rawgit.com/medialize/URI.js/gh-pages/src/URI.js').getContentText());

  var params = {
    'followRedirects': false,
    'muteHttpExceptions': true
  };

  var baseUrl = urlProtocol(url) + "://" + urlHostname(url),
      response = UrlFetchApp.fetch(url, params),
      responseCode = response.getResponseCode();

  if(response.getHeaders()['Location']){
    var redirectedUrl = getRedirects(baseUrl + response.getHeaders()['Location']);
    return redirectedUrl;
  } else {
    return url;
  }
}