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.
if (urlString starts with http:// or https://)
//do this
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.
if (urlString starts with http:// or https://)
//do this
var pat = /^https?:\/\//i;
if (pat.test(urlString))
{
//do stuff
}
For protocol relative urls, use this regex:
/^https?:\/\/|^\/\//i
If you only need to test for http://
or https://
then the most efficient way is:
if (urlString.indexOf('http://') === 0 || urlString.indexOf('https://') === 0)
However, I would suggest a more universal, non case-sensitive, protocol-agnostic approach:
var r = new RegExp('^(?:[a-z]+:)?//', 'i');
r.test('http://example.com'); // true - regular http absolute URL
r.test('HTTP://EXAMPLE.COM'); // true - HTTP upper-case absolute URL
r.test('https://www.exmaple.com'); // true - secure http absolute URL
r.test('ftp://example.com/file.txt'); // true - file transfer absolute URL
r.test('//cdn.example.com/lib.js'); // true - protocol-relative absolute URL
r.test('/myfolder/test.txt'); // false - relative URL
r.test('test'); // false - also relative URL
^(?:[a-z]+:)?//
^
- beginning of the string
(?:
- beginning of a non-captured group
[a-z]+
- any character of 'a' to 'z' 1 or more times
:
- string (colon character)
)?
- end of the non-captured group. Group appearing 0 or 1 times
//
- string (two forward slash characters)
'i'
- non case-sensitive flag
Use a regex:
if (/^(?:[a-z]+:)?\/\//i.test(url))
A very fast and very flexible check is:
if (url.indexOf('://') > 0 || url.indexOf('//') === 0 ) {
// URL is absolute; either "http://example.com" or "//example.com"
} else {
// URL is relative
}
This will recognize an absolute URL, if:
Update
Here is a quick function that returns true/false for the given URL:
function isUrlAbsolute(url) {
return (url.indexOf('://') > 0 || url.indexOf('//') === 0);
}
And same in ES6:
const isUrlAbsolute = (url) => (url.indexOf('://') > 0 || url.indexOf('//') === 0)
Update 2
To additionally address URLs in format /redirect?target=http://example.org
I recommend to use this code:
function isUrlAbsolute(url) {
if (url.indexOf('//') === 0) {return true;} // URL is protocol-relative (= absolute)
if (url.indexOf('://') === -1) {return false;} // URL has no protocol (= relative)
if (url.indexOf('.') === -1) {return false;} // URL does not contain a dot, i.e. no TLD (= relative, possibly REST)
if (url.indexOf('/') === -1) {return false;} // URL does not contain a single slash (= relative)
if (url.indexOf(':') > url.indexOf('/')) {return false;} // The first colon comes after the first slash (= relative)
if (url.indexOf('://') < url.indexOf('.')) {return true;} // Protocol is defined before first dot (= absolute)
return false; // Anything else must be relative
}
And the same in short form and ES 6
// Traditional JS, shortened
function isUrlAbsolute(url) {
return url.indexOf('//') === 0 ? true : url.indexOf('://') === -1 ? false : url.indexOf('.') === -1 ? false : url.indexOf('/') === -1 ? false : url.indexOf(':') > url.indexOf('/') ? false : url.indexOf('://') < url.indexOf('.') ? true : false;
}
// ES 6
const isUrlAbsolute = (url) => (url.indexOf('//') === 0 ? true : url.indexOf('://') === -1 ? false : url.indexOf('.') === -1 ? false : url.indexOf('/') === -1 ? false : url.indexOf(':') > url.indexOf('/') ? false : url.indexOf('://') < url.indexOf('.') ? true : false)
Here are some test cases:
// Test
console.log( isUrlAbsolute('http://stackoverflow.com') ) // -> true
console.log( isUrlAbsolute('//stackoverflow.com') ) // -> true
console.log( isUrlAbsolute('stackoverflow.com') ) // -> false
console.log( isUrlAbsolute('Ftp://example.net') ) // -> true
console.log( isUrlAbsolute('/redirect?target=http://example.org') ) // -> false
(?:^[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
}
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;
var adress = 'http://roflmao.com';
if (adress.substr(0,7) == 'http://' || adress.substr(0,8) == 'https://') {
//
}
Following function will get called when click even occurs on a hyperlink i.e 'a' tag if the tag contains url will be relative or contains same host then that new page will get loaded into same browser tab if it contains different url then page will load in new browser tab
jQuery(document).ready(function() {
$('a').click(function(){
var a = this;
var a_href = $(this).attr('href');
var regex = new RegExp('^(?:[a-z]+:)?//', 'i');
if(a.host == location.host || regex.test(a_href) == false){
a.target = '_self';
}else{
a.target = '_blank';
}
});
});
Here's a bulletproof approach to the problem:
Let the browser handle everything for us. 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 isExternalURL = url.toLowerCase().indexOf('http://') === 0 || url.toLowerCase().indexOf('https://') === 0 ;