What\'s the fastest method to detect if foo=\'http://john.doe\'
is an external url (in comparsion to window.location.href
)?
I've been using psuedosavant's method, but ran into a few cases where it triggered false positives, such as domain-less links ( /about
, image.jpg
) and anchor links ( #about
). The old method would also give inaccurate results for different protocols ( http
vs https
).
Here's my slightly modified version:
var checkDomain = function(url) {
if ( url.indexOf('//') === 0 ) { url = location.protocol + url; }
return url.toLowerCase().replace(/([a-z])?:\/\//,'$1').split('/')[0];
};
var isExternal = function(url) {
return ( ( url.indexOf(':') > -1 || url.indexOf('//') > -1 ) && checkDomain(location.href) !== checkDomain(url) );
};
Here are some tests with the updated function:
isExternal('http://google.com'); // true
isExternal('https://google.com'); // true
isExternal('//google.com'); // true (no protocol)
isExternal('mailto:mail@example.com'); // true
isExternal('http://samedomain.com:8080/port'); // true (same domain, different port)
isExternal('https://samedomain.com/secure'); // true (same domain, https)
isExternal('http://samedomain.com/about'); // false (same domain, different page)
isExternal('HTTP://SAMEDOMAIN.COM/about'); // false (same domain, but different casing)
isExternal('//samedomain.com/about'); // false (same domain, no protocol)
isExternal('/about'); // false
isExternal('image.jpg'); // false
isExternal('#anchor'); // false
It's more accurate overall, and it even ends up being marginally faster, according to some basic jsperf tests. If you leave off the .toLowerCase()
for case-insensitive testing, you can speed it up even more.