54

I need to validate a url in variable with jQuery, but can't use validate-plugin. Is there a simple way to do this?

gen_Eric
  • 223,194
  • 41
  • 299
  • 337
Martti Laine
  • 12,655
  • 22
  • 68
  • 102

7 Answers7

140

You can use the same regex that the validation plugin does (updated to latest regex on May 23rd, 2015):

function isUrlValid(url) {
    return /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(url);
}

var testCases = [
    "http://www.google.com/",
    "https://www.google.com/",
    "ftp://www.google.com/",
    "http://google.com/",
    "http://google.com",
    "https://google.com",
    "http://www.google.com:80/",
    "https://www.google.com:443/",
    "http://127.0.0.1/",
    "http://127.0.0.1:9200/",
    "www.site.com",
    "x:",
    "http://",
    "javascript:alert('xss')",
    "http://w",
    "http:",
    "derp://www.google.com",
    "http://localserver"
],  div = document.getElementById("output");

for(var i=0; i < testCases.length; i++) {
    var test = testCases[i];
    div.innerHTML += (isUrlValid(test) ? "<span class='valid'>valid</span>:   " : "<span class='invalid'>invalid</span>: ") + "" + test + "\n";
}
.valid { color: green; }
.invalid { color: red; }
<pre id="output"></pre>

This handles unicode, etc so it's a bit verbose. Source is the validation plugin itself. A few notes: it is probably what you want, but it is not strictly correct. Typically you need to choose a slightly different regex if you want to accept things like http://w and http://localserver which are valid in an intranet environment but not typically allowed in most web forms. In a way, this regex is safer because it requires a FQDN in such cases. Similarly other examples like custom protocols are rejected here, but are valid and do work for many things used today. If you're asking users "what's your homepage?" in a form though...you likely want to exclude these anyway.

Anyone finding this later: please feel free to test additional test cases with the snippet I included and update the answer if you feel a new common case should be mentioned. I re-wrote the answer with the latest regex and in this format to better serve the community.

scunliffe
  • 62,582
  • 25
  • 126
  • 161
Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • 3
    Worked very well. Simple too. Would love it if you can expand the answer to show option for auto adding http:// ? – TheBlackBenzKid Feb 23 '12 at 22:51
  • 1
    Additionally it accepts "derp://www.google.com" as a valid url. – jnovack May 23 '15 at 14:13
  • @user1063287 those are valid URLs, I can have a server named `w`. Only a hostname is not a valid URL. – Nick Craver May 23 '15 at 14:42
  • @jnovack That is a valid URL. URLs are not constrained to only the http and https protocols. Any custom protocol is valid. This is how things like steam links and links between apps on your phone work. – Nick Craver May 23 '15 at 14:43
  • I'm going to disagree on a technicality, which was the original intent of my message (sorry I was not clear). 'derp://' is a URI, not a URL. – jnovack May 23 '15 at 15:59
  • @jnovack It is still both a valid URI and a valid URL. The RFC fo URLs (1738) specifies the syntax of schemes and *specific* schemes are enumerated (section 3 if I remember correctly) it is specifically noted **not** to be an exhaustive list. Custom protocols are allowed in URLs and are quite widely used on the internet today. – Nick Craver May 23 '15 at 16:33
  • @HelpNeeder the latest regex doesn't have this issue - I improved the answer quite a bit and hopefully people can/will just add test cases when warranted...unfortunately I don't have as much time as I'd like to tend to 6,000+ answers these days :-/ – Nick Craver May 23 '15 at 16:51
  • @NickCraver It wont work with `*.co.in, *.co.uk and file:///` protocol. – immayankmodi Oct 27 '15 at 12:44
  • In order to validate the FTP as a valid URL just use this `/^(https?|ftp):\/\//i` – Alvaro Jun 09 '16 at 14:52
  • Does this actually check if a URL goes to a 404, or does this just check for format/syntax validation? – AndyWarren Jul 13 '16 at 16:45
  • Which part do I remove to not require any protocol `http/https/ftp/etc`? – MultiDev Sep 13 '16 at 13:34
  • It works fine when I paste or type the url in the input box. However, I found that it's not working on real time validate when press Backspace keyboard. Here is example: valid http://www.jinai-cl invalid http://www.jinai- and valid http://www.jinai . Any help please. – Daroath Sep 06 '17 at 10:09
  • This won't work for url without any protocol like 'www.abc.com' – Suhas Bhattu Jul 03 '19 at 04:35
  • how to add local host in it as it is trturnin false to http://localhost/ – Swarna Sekhar Dhar Aug 13 '20 at 15:28
35

Thank you very much Meo and Nick, I put both your answers together and it works just great.

if(/^(http|https|ftp):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/i.test($("#url").val())){
    alert("valid URL");
} else {
    alert("invalid URL");
}
Ersin Demirtas
  • 666
  • 6
  • 14
13

If you are sure that your audience is using HTML5, you can use type="url" to validate the text string. You could also dynamically create an input element, set the type and test whether the variable is valid URL or not.

The following is based on a blog post from https://www.raymondcamden.com/2016/10/19/using-html-form-validation-in-pure-javascript

var elm;
function isValidURL(u){
  if(!elm){
    elm = document.createElement('input');
    elm.setAttribute('type', 'url');
  }
  elm.value = u;
  return elm.validity.valid;
}

console.log(isValidURL('http://www.google.com/'));
console.log(isValidURL('//google.com'));
console.log(isValidURL('google.com'));
Martti Laine
  • 12,655
  • 22
  • 68
  • 102
James Moberg
  • 4,360
  • 1
  • 22
  • 21
9
var url = $('input.surl').val();
var url_validate = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
if(!url_validate.test(url)){
   alert('error');
}
else{
   alert('success');
}
Abdo-Host
  • 2,470
  • 34
  • 33
6

yes with a regex:

/^(http|https|ftp):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/ix
meo
  • 30,872
  • 17
  • 87
  • 123
3

you Want to validate your URL:

Please pass the URL in this function then this will give you true OR false.

See Function :

<script>
function isUrl(s) {
    var regexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/
    return regexp.test(s);
}

isUrl(yourURL);
</script>
Shahzad Barkati
  • 2,532
  • 6
  • 25
  • 33
Vishnu Sharma
  • 1,357
  • 12
  • 11
3

Code :

var re = /^(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/;
re.test('http://www.goole.in');
Musakkhir Sayyed
  • 7,012
  • 13
  • 42
  • 65
Akash Mane
  • 31
  • 2
  • 1
    Some explanation would improve your answer. Also, question was how to validate an URL stored in a *variable*. – dakab Jan 02 '16 at 19:26