How can I test a URL if it is a relative or absolute path in Javascript or jQuery? I want to handle accordingly depending if the passed in URL is a local or external path.
You can use a try, catch block to help with this. Rather than using a regular expression, you can use the URL interface at every step.
isExternalUrl (urlString) {
try {
const url = new URL(urlString) // THROW ON MISSING SCHEME
// DOES THIS URL ORIGINATE FROM THIS WEBSITE?
if (url.origin !== new URL(document.URL, document.baseURI).origin) {
return true // IS EXTERNAL URL
}
} catch (_e) {
// THROWS WHEN URL DOES NOT HAVE A SCHEME
new URL(urlString, document.baseURL) // THROW AN EXCEPTION IF THE URL IS TRULY MALFORMED IN SOME WAY
}
return false
}
Here's a pretty robust solution for the browser environment:
Let the browser handle everything. No need for some complicated/error prone regexes.
const isAbsoluteUrl = (url) => {
const link = document.createElement('a');
link.href = url;
return link.origin + link.pathname + link.search + link.hash === url;
};
var external = RegExp('^(https?:)?//');
if(external.test(el)){
// do something
}
EDIT:
With the next regular expression, you can even check if the link goes to the same domain or to an external one:
var external = RegExp('^((f|ht)tps?:)?//(?!' + location.host + ')');
if(external.test(el)){
// do something
}
Don't use low-level stuff like regexp etc. These things have been solved by so many other people. Especially the edge cases.
Have a look at URI.js, it should do the job: http://medialize.github.io/URI.js/docs.html#is
var uri = new URI("http://example.org/");
uri.is("absolute") === true;
(?:^[a-z][a-z0-9+.-]*:|\/\/)
regex explanation
The other solutions listed here would fail for links like mailto:evan@nylas.com
RFC 3986 defines a Scheme as:
scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
3.1. Scheme https://tools.ietf.org/html/rfc3986#section-3.1
While the protocol-relative url is technically valid as per section 4.2, Paul Irish has swung back the other way and considers this an anti-pattern. See http://www.paulirish.com/2010/the-protocol-relative-url/
4.2. Relative Reference http://tools.ietf.org/html/rfc3986#section-4.2
If you'd like the regex without protocol-relative url's use:
^[a-z][a-z0-9+.-]*:
To see a full list of other types of valid uri edge cases, check out the list here: https://en.wikipedia.org/wiki/URI_scheme
Nowdays, when a lot of services use protocol-relative URL (eg. //cdn.example.com/libary.js), this method is safer:
var isAbsolute = new RegExp('^([a-z]+://|//)', 'i');
if (isAbsolute.test(urlString)) {
// go crazy here
}