I wanted to add another answer here as we've come into the age of the Sharepoint Add-In model and this won't work if you want to get the top level site collection from an Add-In, since you'll either be using a Provider Hosted add-in where your page is hosted off-site or Sharepoint Hosted add-in where it's hosted in the Add-In web. These answers will give you the URL for the Add-In web.
I got the top level site collection url from my Sharepoint Hosted add-in by using the following code:
//Get the URI decoded URLs.
hostweburl =
decodeURIComponent(
getQueryStringParameter("SPHostUrl")
);
// Set toplevelurl to the top level site collection url
toplevelurl = hostweburl.split("://")[0] + "://" + hostweburl.split("://")[1].split('/')[0];
Of course if you actually want to take any actions on the top level site collection, remember to use the Cross Domain Library, specifically SP.ProxyWebRequestExecutorFactory
and SP.AppContextSite
so something like:
clientContext = new SP.ClientContext(addinweburl);
var factory = new SP.ProxyWebRequestExecutorFactory(addinweburl);
clientContext.set_webRequestExecutorFactory(factory);
topContext = new SP.AppContextSite(clientContext, toplevelurl);
I won't go into using the CDL as that's covered well elsewhere and it's way beyond the scope of this question.
Hope this helps!