web-dev-qa-db-fra.com

Vérifier si une chaîne JavaScript est une URL

Existe-t-il un moyen en JavaScript de vérifier si une chaîne est une URL?

Les RegExes sont exclus car l'URL est probablement écrite comme suit: stackoverflow; c'est-à-dire qu'il pourrait ne pas avoir .com, www ou http.

153
Bruno

Une question connexe avec une réponse:

Correspondance URL jave regex

Ou cette expression rationnelle de Devshed :

function validURL(str) {
  var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
    '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name
    '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
    '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
    '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
    '(\\#[-a-z\\d_]*)?$','i'); // fragment locator
  return !!pattern.test(str);
}
68
Tom Gullen
function isURL(str) {
  var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
  '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|'+ // domain name
  '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
  '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
  '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
  '(\\#[-a-z\\d_]*)?$','i'); // fragment locator
  return pattern.test(str);
}
156
Zemljoradnik

Plutôt que d'utiliser une expression régulière, je vous recommanderais d'utiliser un élément d'ancrage. 

lorsque vous définissez la propriété href d'un anchor, diverses autres propriétés sont définies. 

var parser = document.createElement('a');
parser.href = "http://example.com:3000/pathname/?search=test#hash";

parser.protocol; // => "http:"
parser.hostname; // => "example.com"
parser.port;     // => "3000"
parser.pathname; // => "/pathname/"
parser.search;   // => "?search=test"
parser.hash;     // => "#hash"
parser.Host;     // => "example.com:3000"

la source

Cependant, si la valeur href est liée à n'est pas une URL valide, la valeur de ces propriétés auxiliaires sera la chaîne vide.

Edit: comme indiqué dans les commentaires: si une URL non valide est utilisée, les propriétés de l'URL actuelle peuvent être remplacées.

Donc, tant que vous ne transmettez pas l'URL de la page en cours, vous pouvez faire quelque chose comme:

function isValidURL(str) {
   var a  = document.createElement('a');
   a.href = str;
   return (a.Host && a.Host != window.location.Host);
}
74
Luke

Vous pouvez essayer d'utiliser le constructeur URL : s'il ne lève pas, la chaîne est une URL valide:

const isValidUrl = (string) => {
  try {
    new URL(string);
    return true;
  } catch (_) {
    return false;  
  }
}
36
Pavlo

Pour valider l'URL à l'aide de javascript est présenté ci-dessous

function ValidURL(str) {
  var regex = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/;
  if(!regex .test(str)) {
    alert("Please enter valid URL.");
    return false;
  } else {
    return true;
  }
}
25
kavitha Reddy

Amélioration de la réponse acceptée ...

  • Vérifier si ftp/ftps est le protocole
  • Double échappement pour les barres obliques inverses (\\)
  • Garantit que les domaines ont un point et une extension (.com .io .xyz)
  • Permet la présence de deux points complets (:) dans le chemin, par exemple. http://thingiverse.com/download:1894343
  • Autorise l'esperluette (&) dans le chemin, par ex. http://en.wikipedia.org/wiki/Procter_&_Gamble
  • Permet le symbole @ dans le chemin, par exemple. https://medium.com/@techytimo

    isURL(str) {
      var pattern = new RegExp('^((ft|htt)ps?:\\/\\/)?'+ // protocol
      '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name and extension
      '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
      '(\\:\\d+)?'+ // port
      '(\\/[-a-z\\d%@_.~+&:]*)*'+ // path
      '(\\?[;&a-z\\d%@_.,~+&:=-]*)?'+ // query string
      '(\\#[-a-z\\d_]*)?$','i'); // fragment locator
      return pattern.test(str);
    }
    
20
TechyTimo

Comptez sur une bibliothèque: https://www.npmjs.com/package/valid-url

import { isWebUri } from 'valid-url';
// ...
if (!isWebUri(url)) {
    return "Not a valid url.";
}
19
Michael Bushe

J'utilise la fonction ci-dessous pour valider l'URL avec ou sans http/https:

function isValidURL(string) {
  var res = string.match(/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g);
  if (res == null)
    return false;
  else
    return true;
};

var testCase1 = "http://en.wikipedia.org/wiki/Procter_&_Gamble";
console.log(isValidURL(testCase1)); // return true

var testCase2 = "http://www.google.com/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&docid=nIv5rk2GyP3hXM&tbnid=isiOkMe3nCtexM:&ved=0CAUQjRw&url=http%3A%2F%2Fanimalcrossing.wikia.com%2Fwiki%2FLion&ei=ygZXU_2fGKbMsQTf4YLgAQ&bvm=bv.65177938,d.aWc&psig=AFQjCNEpBfKnal9kU7Zu4n7RnEt2nerN4g&ust=1398298682009707";
console.log(isValidURL(testCase2)); // return true

var testCase3 = "https://sdfasd";
console.log(isValidURL(testCase3)); // return false

var testCase4 = "dfdsfdsfdfdsfsdfs";
console.log(isValidURL(testCase4)); // return false

var testCase5 = "magnet:?xt=urn:btih:123";
console.log(isValidURL(testCase5)); // return false

var testCase6 = "https://stackoverflow.com/";
console.log(isValidURL(testCase6)); // return true

var testCase7 = "https://w";
console.log(isValidURL(testCase7)); // return false

var testCase8 = "https://sdfasdp.ppppppppppp";
console.log(isValidURL(testCase8)); // return false

16
VicJordan

Voici encore une autre méthode.

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'));
console.log(isValidURL('localhost:8000'));

10
Ryan

(Je n'ai pas de représentants à commenter ValidURL example; postez donc ceci comme réponse.)

Bien que l'utilisation d'URL relatives au protocole ne soit pas encouragée ( L'URL relative au protocole ), elles sont parfois utilisées. Pour valider une telle URL avec une expression régulière, la partie protocole peut être facultative, par exemple:

function isValidURL(str) {
    var pattern = new RegExp('^((https?:)?\\/\\/)?'+ // protocol
        '(?:\\S+(?::\\S*)?@)?' + // authentication
        '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name
        '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
        '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
        '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
        '(\\#[-a-z\\d_]*)?$','i'); // fragment locater
    if (!pattern.test(str)) {
        return false;
    } else {
        return true;
    }
}

Comme d'autres l'ont fait remarquer, l'expression régulière ne semble pas être la meilleure approche pour valider les URL, cependant. 

8
ko la

Je ne peux pas commenter le message le plus proche # 5717133 , mais voici comment j'ai compris comment utiliser @ tom-gullen regex.

/^(https?:\/\/)?((([a-z\d]([a-z\d-]*[a-z\d])*)\.)+[a-z]{2,}|((\d{1,3}\.){3}\d{1,3}))(\:\d+)?(\/[-a-z\d%_.~+]*)*(\?[;&a-z\d%_.~+=-]*)?(\#[-a-z\d_]*)?$/i
5
iamnewton

Comme cela a été noté, l'expression rationnelle parfaite est évasive, mais semble tout de même être une approche raisonnable (les alternatives sont les tests côté serveur ou le nouvel expérimental URL API ). Cependant, les réponses les mieux classées retournent souvent la valeur false pour les URL communes, mais pire encore, votre application/votre page resterait figée pendant quelques minutes, même avec une chaîne aussi simple que isURL('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'). Cela a été souligné dans certains commentaires, mais le plus probablement n'ont pas été mal renseigné. Une telle suspension rend ce code inutilisable dans toute application sérieuse. Je pense que cela est dû aux ensembles répétés insensibles à la casse dans le code comme ((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|' .... Sortez le 'i' et il ne pendra pas mais ne fonctionnera bien sûr pas comme vous le souhaitez. Mais même avec l'indicateur Ignorer la casse, ces tests rejettent les valeurs Unicode élevées autorisées.

Le meilleur déjà mentionné est:

function isURL(str) {
  return /^(?:\w+:)?\/\/([^\s\.]+\.\S{2}|localhost[\:?\d]*)\S*$/.test(str); 
}

Cela vient de Github segmentio/is-url . La bonne chose à propos d'un référentiel de code est que vous pouvez voir les tests et tous les problèmes, ainsi que les chaînes de test qui les parcourent. Il y a une branche qui autoriserait des chaînes manquantes dans le protocole comme google.com, bien que vous fassiez probablement trop d'hypothèses à ce moment-là. Le référentiel a été mis à jour et je ne prévois pas d'essayer de garder un miroir ici. Il a été divisé en tests séparés pour éviter RegEx redos qui pourrait être exploité pour les attaques par DOS (je ne pense pas que vous ayez à vous en soucier avec js côté client, mais vous devez vous soucier de votre page suspendu depuis si longtemps que votre visiteur quitte votre site).

Il y a un autre dépôt que j'ai vu qui pourrait même être meilleur pour isURL à dperini/regex-weburl.js, mais c'est extrêmement complexe. Il contient une liste de test plus grande d'URL valides et non valides. Le simple ci-dessus passe toujours tous les points positifs et ne parvient pas à bloquer quelques négatifs impairs comme http://a.b--c.de/ ainsi que les ips spéciaux.

Quel que soit votre choix, exécutez cette fonction, que j'ai adaptée à partir des tests de dperini/regex-weburl.js, tout en utilisant l'inpecteur Outils de développement de votre navigateur.

function testIsURL() {
//should match
console.assert(isURL("http://foo.com/blah_blah"));
console.assert(isURL("http://foo.com/blah_blah/"));
console.assert(isURL("http://foo.com/blah_blah_(wikipedia)"));
console.assert(isURL("http://foo.com/blah_blah_(wikipedia)_(again)"));
console.assert(isURL("http://www.example.com/wpstyle/?p=364"));
console.assert(isURL("https://www.example.com/foo/?bar=baz&inga=42&quux"));
console.assert(isURL("http://✪df.ws/123"));
console.assert(isURL("http://userid:[email protected]:8080"));
console.assert(isURL("http://userid:[email protected]:8080/"));
console.assert(isURL("http://[email protected]"));
console.assert(isURL("http://[email protected]/"));
console.assert(isURL("http://[email protected]:8080"));
console.assert(isURL("http://[email protected]:8080/"));
console.assert(isURL("http://userid:[email protected]"));
console.assert(isURL("http://userid:[email protected]/"));
console.assert(isURL("http://142.42.1.1/"));
console.assert(isURL("http://142.42.1.1:8080/"));
console.assert(isURL("http://➡.ws/䨹"));
console.assert(isURL("http://⌘.ws"));
console.assert(isURL("http://⌘.ws/"));
console.assert(isURL("http://foo.com/blah_(wikipedia)#cite-1"));
console.assert(isURL("http://foo.com/blah_(wikipedia)_blah#cite-1"));
console.assert(isURL("http://foo.com/unicode_(✪)_in_parens"));
console.assert(isURL("http://foo.com/(something)?after=parens"));
console.assert(isURL("http://☺.damowmow.com/"));
console.assert(isURL("http://code.google.com/events/#&product=browser"));
console.assert(isURL("http://j.mp"));
console.assert(isURL("ftp://foo.bar/baz"));
console.assert(isURL("http://foo.bar/?q=Test%20URL-encoded%20stuff"));
console.assert(isURL("http://مثال.إختبار"));
console.assert(isURL("http://例子.测试"));
console.assert(isURL("http://उदाहरण.परीक्षा"));
console.assert(isURL("http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com"));
console.assert(isURL("http://1337.net"));
console.assert(isURL("http://a.b-c.de"));
console.assert(isURL("http://223.255.255.254"));
console.assert(isURL("postgres://u:[email protected]:5702/db"));
console.assert(isURL("https://[email protected]/13176"));

//SHOULD NOT MATCH:
console.assert(!isURL("http://"));
console.assert(!isURL("http://."));
console.assert(!isURL("http://.."));
console.assert(!isURL("http://../"));
console.assert(!isURL("http://?"));
console.assert(!isURL("http://??"));
console.assert(!isURL("http://??/"));
console.assert(!isURL("http://#"));
console.assert(!isURL("http://##"));
console.assert(!isURL("http://##/"));
console.assert(!isURL("http://foo.bar?q=Spaces should be encoded"));
console.assert(!isURL("//"));
console.assert(!isURL("//a"));
console.assert(!isURL("///a"));
console.assert(!isURL("///"));
console.assert(!isURL("http:///a"));
console.assert(!isURL("foo.com"));
console.assert(!isURL("rdar://1234"));
console.assert(!isURL("h://test"));
console.assert(!isURL("http:// shouldfail.com"));
console.assert(!isURL(":// should fail"));
console.assert(!isURL("http://foo.bar/foo(bar)baz quux"));
console.assert(!isURL("ftps://foo.bar/"));
console.assert(!isURL("http://-error-.invalid/"));
console.assert(!isURL("http://a.b--c.de/"));
console.assert(!isURL("http://-a.b.co"));
console.assert(!isURL("http://a.b-.co"));
console.assert(!isURL("http://0.0.0.0"));
console.assert(!isURL("http://10.1.1.0"));
console.assert(!isURL("http://10.1.1.255"));
console.assert(!isURL("http://224.1.1.1"));
console.assert(!isURL("http://1.1.1.1.1"));
console.assert(!isURL("http://123.123.123"));
console.assert(!isURL("http://3628126748"));
console.assert(!isURL("http://.www.foo.bar/"));
console.assert(!isURL("http://www.foo.bar./"));
console.assert(!isURL("http://.www.foo.bar./"));
console.assert(!isURL("http://10.1.1.1"));}

Et ensuite, testez cette chaîne de 'a'.

Voir ceci comparaison des expressions rationnelles isURL de Mathias Bynens pour plus d'informations avant de publier une expression rationnelle apparemment géniale.

5
aamarks

Une fonction que j'ai utilisée pour valider une URL "chaîne" est:

var matcher = /^(?:\w+:)?\/\/([^\s\.]+\.\S{2}|localhost[\:?\d]*)\S*$/;

function isUrl(string){
  return matcher.test(string);
}

Cette fonction retournera un booléen si la chaîne est une URL.

Exemples:

isUrl("https://google.com");     // true
isUrl("http://google.com");      // true
isUrl("http://google.de");       // true
isUrl("//google.de");            // true
isUrl("google.de");              // false
isUrl("http://google.com");      // true
isUrl("http://localhost");       // true
isUrl("https://sdfasd");         // false
4
Chris

cela fonctionne avec moi

function isURL(str) {
  var regex = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/;
  var pattern = new RegExp(regex); 
return pattern.test(str);
}
2
HeshamSalama

Dans mon cas, ma seule exigence est que l'entrée de l'utilisateur ne soit pas interprétée comme un lien relatif lorsqu'elle est placée dans le href d'une balise et que les réponses ici étaient soit un bit OTT pour cela, soit des URL autorisées ne répondant pas à mes exigences. est ce que je vais avec:

^https?://.+$

La même chose pourrait être réalisée assez facilement sans regex.

1
rdans

La question demande une méthode de validation pour une URL telle que stackoverflow, sans le protocole ou un point dans le nom d'hôte. Donc, il ne s’agit pas de valider l’URL sintax, mais de vérifier s’il s’agit d’une URL valide, en l’appelant réellement.

J'ai essayé plusieurs méthodes pour savoir si l'URL true existe et peut être appelé à partir du navigateur, mais je n'ai trouvé aucun moyen de tester en javascript l'en-tête de réponse de l'appel:

  • l'ajout d'un élément d'ancrage suffit pour déclencher la méthode click()
  • passer un appel ajax à l'URL difficile avec 'GET' convient, mais il existe diverses limitations dues aux politiques CORS. Ce n'est pas le cas d'utiliser ajax;.
  • l'utilisation de l'API fetch a une solution de contournement similaire à ajax.
  • l’autre problème est que mon serveur est sous le protocole https et lève une exception lors de l’appel d’URL non sécurisées.

La meilleure solution à laquelle je puisse penser consiste donc à obtenir un outil pour exécuter CURL en utilisant javascript en essayant quelque chose comme curl -I <url>. Malheureusement, je n'en ai trouvé aucune et en apparence, ce n'est pas possible. J'apprécierai vos commentaires à ce sujet.

Mais au final, j’ai un serveur qui exécute PHP et comme j’utilise Ajax pour presque toutes mes requêtes, j’ai écrit une fonction côté serveur pour y exécuter la requête curl et revenir au navigateur. 

En ce qui concerne l'URL de mot unique sur la question 'stackoverflow', cela me mènera à https://daniserver.com.ar/stackoverflow, où daniserver.com.ar est mon propre domaine. 

1
Daniel Faure

Vous pouvez utiliser l'API native URL :

  const isUrl = string => {
      try { return Boolean(new URL(string)); }
      catch(e){ return false; }
  }
1
Aral Roca

C'est assez difficile à faire avec une regex pure car les URL présentent de nombreux «inconvénients».

  1. Par exemple, les noms de domaine ont des restrictions compliquées sur les traits d'union:

    une. Il est autorisé d'avoir plusieurs traits d'union consécutifs au milieu.

    b. mais le premier et le dernier caractère du nom de domaine ne peuvent pas être un trait d'union

    c. Le 3ème et le 4ème caractère ne peuvent pas être deux traits d'union 

  2. De même, le numéro de port ne peut être compris que dans la plage 1-65535. Il est facile de vérifier si vous extrayez la partie de port et que vous convertissez en int, mais il est assez difficile de vérifier avec une expression régulière.

  3. Il n’existe pas non plus de moyen simple de vérifier les extensions de domaine valides. Certains pays ont des domaines de second niveau (tels que "co.uk"), ou l'extension peut être un long mot tel que ".international". Et de nouveaux TLD sont ajoutés régulièrement. Ce type de choses ne peut être vérifié qu'avec une liste codée en dur. (voir https://en.wikipedia.org/wiki/Top-level_domain )

  4. Ensuite, il y a les URL des aimants, les adresses FTP, etc. Toutes ont des exigences différentes.

Néanmoins, voici une fonction qui gère à peu près tout, sauf:

  • Cas 1. c
  • Accepte tout numéro de port de 1 à 5 chiffres
  • Accepte n'importe quelle extension 2-13 caractères
  • N'accepte pas de ftp, magnet, etc ...

function isValidURL(input) {
    pattern = '^(https?:\\/\\/)?' + // protocol
        '((([a-zA-Z\\d]([a-zA-Z\\d-]{0,61}[a-zA-Z\\d])*\\.)+' + // sub-domain + domain name
        '[a-zA-Z]{2,13})' + // extension
        '|((\\d{1,3}\\.){3}\\d{1,3})' + // OR ip (v4) address
        '|localhost)' + // OR localhost
        '(\\:\\d{1,5})?' + // port
        '(\\/[a-zA-Z\\&\\d%_.~+-:@]*)*' + // path
        '(\\?[a-zA-Z\\&\\d%_.,~+-:@=;&]*)?' + // query string
        '(\\#[-a-zA-Z&\\d_]*)?$'; // fragment locator
    regex = new RegExp(pattern);
    return regex.test(input);
}

let tests = [];
tests.Push(['', false]);
tests.Push(['http://en.wikipedia.org/wiki/Procter_&_Gamble', true]);
tests.Push(['https://sdfasd', false]);
tests.Push(['http://www.google.com/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&docid=nIv5rk2GyP3hXM&tbnid=isiOkMe3nCtexM:&ved=0CAUQjRw&url=http%3A%2F%2Fanimalcrossing.wikia.com%2Fwiki%2FLion&ei=ygZXU_2fGKbMsQTf4YLgAQ&bvm=bv.65177938,d.aWc&psig=AFQjCNEpBfKnal9kU7Zu4n7RnEt2nerN4g&ust=1398298682009707', true]);
tests.Push(['https://stackoverflow.com/', true]);
tests.Push(['https://w', false]);
tests.Push(['aaa', false]);
tests.Push(['aaaa', false]);
tests.Push(['oh.my', true]);
tests.Push(['dfdsfdsfdfdsfsdfs', false]);
tests.Push(['google.co.uk', true]);
tests.Push(['test-domain.MUSEUM', true]);
tests.Push(['-hyphen-start.gov.tr', false]);
tests.Push(['hyphen-end-.com', false]);
tests.Push(['https://sdfasdp.international', true]);
tests.Push(['https://sdfasdp.pppppppp', false]);
tests.Push(['https://sdfasdp.ppppppppppppppppppp', false]);
tests.Push(['https://sdfasd', false]);
tests.Push(['https://sub1.1234.sub3.sub4.sub5.co.uk/?', true]);
tests.Push(['http://www.google-com.123', false]);
tests.Push(['http://my--testdomain.com', false]);
tests.Push(['http://my2nd--testdomain.com', true]);
tests.Push(['http://thingiverse.com/download:1894343', true]);
tests.Push(['https://medium.com/@techytimo', true]);
tests.Push(['http://localhost', true]);
tests.Push(['localhost', true]);
tests.Push(['localhost:8080', true]);
tests.Push(['localhost:65536', true]);
tests.Push(['localhost:80000', false]);
tests.Push(['magnet:?xt=urn:btih:123', true]);

for (let i = 0; i < tests.length; i++) {
    console.log('Test #' + i + (isValidURL(tests[i][0]) == tests[i][1] ? ' passed' : ' failed') + ' on ["' + tests[i][0] + '", ' + tests[i][1] + ']');
}

1
Caner

Cela semble être l’un des problèmes les plus difficiles en CS;)

Voici une autre solution incomplète qui fonctionne assez bien pour moi et mieux que les autres que j'ai vues ici. J'utilise une entrée [type = url] pour cela afin de supporter IE11, sinon ce serait beaucoup plus simple d'utiliser window.URL pour effectuer la validation à la place:

const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
function isValidIpv4(ip) {
  if (!ipv4Regex.test(ip)) return false;
  return !ip.split('.').find(n => n > 255);
}

const domainRegex = /(?:[a-z0-9-]{1,63}\.){1,125}[a-z]{2,63}$/i;
function isValidDomain(domain) {
  return isValidIpv4(domain) || domainRegex.test(domain);
}

let input;
function validateUrl(url) {
  if (! /^https?:\/\//.test(url)) url = `http://${url}`; // assuming Babel is used
  // to support IE11 we'll resort to input[type=url] instead of window.URL:
  // try { return isValidDomain(new URL(url).Host) && url; } catch(e) { return false; }
  if (!input) { input = document.createElement('input'); input.type = 'url'; }
  input.value = url;
  if (! input.validity.valid) return false;
  const domain = url.split(/^https?:\/\//)[1].split('/')[0].split('@').pop();
  return isValidDomain(domain) && url;
}

console.log(validateUrl('google'), // false
  validateUrl('user:[email protected]'),
  validateUrl('https://google.com'),
  validateUrl('100.100.100.100/abc'),
  validateUrl('100.100.100.256/abc')); // false

Pour accepter des entrées incomplètes telles que "www.mondomaine.com", il sera également valide si le protocole est "http" dans ces cas et renvoyer l'URL valide si l'adresse est valide. Il retourne false lorsqu'il est invalide.

Il prend également en charge les domaines IPv4, mais pas IPv6.

0
rosenfeld

Utilisez validator.js

ES6

import isURL from 'validator/lib/isURL'

isURL(string)

Non ES6

var validator = require('validator');

validator.isURL(string)

Vous pouvez également ajuster le comportement de cette fonction en passant l'objet options facultatif comme deuxième argument de isURL.

Voici l'objet options par défaut:

let options = {
    protocols: [
        'http',
        'https',
        'ftp'
    ],
    require_tld: true,
    require_protocol: false,
    require_Host: true,
    require_valid_protocol: true,
    allow_underscores: false,
    Host_whitelist: false,
    Host_blacklist: false,
    allow_trailing_dot: false,
    allow_protocol_relative_urls: false,
    disallow_auth: false
}

isURL(string, options)

Host_whitelist et Host_blacklist peuvent être des tableaux d'hôtes. Ils supportent également les expressions régulières.

let options = {
    Host_blacklist: ['foo.com', 'bar.com'],
}

isURL('http://foobar.com', options) // => true
isURL('http://foo.bar.com/', options) // => true
isURL('http://qux.com', options) // => true

isURL('http://bar.com/', options) // => false
isURL('http://foo.com/', options) // => false


options = {
    Host_blacklist: ['bar.com', 'foo.com', /\.foo\.com$/],
}

isURL('http://foobar.com', options) // => true
isURL('http://foo.bar.com/', options) // => true
isURL('http://qux.com', options) // => true

isURL('http://bar.com/', options) // => false
isURL('http://foo.com/', options) // => false
isURL('http://images.foo.com/', options) // => false
isURL('http://cdn.foo.com/', options) // => false
isURL('http://a.b.c.foo.com/', options) // => false
0
Ilyich

Si vous pouvez changer le type d'entrée, je pense que cette solution serait beaucoup plus simple:

Vous pouvez simplement utiliser type="url" dans votre entrée et le vérifier avec checkValidity() dans js

Par exemple:

votre.html

<input id="foo" type="url">

votre.js

// The selector is JQuery, but the function is plain JS
$("#foo").on("keyup", function() {
    if (this.checkValidity()) {
        // The url is valid
    } else {
        // The url is invalid
    }
});
0
Daniel Rodríguez

Voici une vérification très simple pour vous assurer qu'il existe un protocole valide et que l'extension de domaine doit comporter au moins deux caractères.

is_valid_url = ( $url ) => {

    let $url_object = null;

    try {
        $url_object = new URL( $url );
    } catch ( $error ) {
        return false;
    }

    const $protocol = $url_object.protocol;
    const $protocol_position = $url.lastIndexOf( $protocol );
    const $domain_extension_position = $url.lastIndexOf( '.' );

    return (
        $protocol_position === 0 &&
        [ 'http:', 'https:' ].indexOf( $protocol ) !== - 1 &&
        $domain_extension_position > 2 && $url.length - $domain_extension_position > 2
    );

};
0
Michael Ecklund

Je pense que l’utilisation de URL API est préférable à un modèle de regex complexe, comme le suggère @pavlo. Il a cependant des inconvénients que nous pouvons résoudre avec un code supplémentaire. Cette approche échoue pour l'URL valide suivante.

//cdn.google.com/script.js

Nous pouvons ajouter le protocole manquant à l'avance pour éviter cela. Il ne parvient pas non plus à détecter l'URL invalide suivante.

http://w
http://..

Alors pourquoi vérifier l'URL entière? nous pouvons simplement vérifier le domaine. J'ai emprunté la regex pour vérifier le domaine de ici

function isValidUrl(string) {
    if (string && string.length > 1 && string.slice(0, 2) == '//') {
        string = 'http:' + string; //dummy protocol so that URL works
    }
    try {
        var url = new URL(string);
        return url.hostname && url.hostname.match(/^([a-z0-9])(([a-z0-9-]{1,61})?[a-z0-9]{1})?(\.[a-z0-9](([a-z0-9-]{1,61})?[a-z0-9]{1})?)?(\.[a-zA-Z]{2,4})+$/) ? true : false;
    } catch (_) {
        return false;
    }
}

L'attribut hostname est une chaîne vide pour javascript:void(0); il fonctionne donc aussi, et vous pouvez également ajouter un vérificateur d'adresse IP. Je voudrais en rester aux API natives et espérer que cela commencera à supporter tout dans un avenir proche. 

0
Munim Munna