Vérifier si une chaîne Javascript est une url

Est-il un moyen en javascript pour vérifier si une chaîne est une url?

RegExes sont exclus parce que l'url est très probablement écrit comme stackoverflow ; c'est-à-dire qu'il pourrait ne pas avoir un .com, www ou http

133
demandé sur ozcanovunc 2011-04-19 17:26:55

17 réponses

une question connexe avec une réponse:

JavaScript correspondance D'URL regex

ou le présent Regexp 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 locater
  if(!pattern.test(str)) {
    alert("Please enter a valid URL.");
    return false;
  } else {
    return true;
  }
}
56
répondu Tom Gullen 2017-05-23 11:33:27
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);
}
158
répondu Zemljoradnik 2015-10-12 14:20:44

plutôt que d'utiliser une expression régulière, je recommande l'utilisation d'un élément d'ancrage.

lorsque vous définissez la propriété href d'un anchor , plusieurs 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"

source

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

Edit: comme l'a souligné dans les commentaires: si une url non valide est utilisé, les propriétés de l'URL courante peut être substitué.

donc, tant que vous ne passez pas dans L'URL de la page actuelle, 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);
}
63
répondu Luke 2016-05-04 13:05:39

vous pouvez essayer d'utiliser URL constructeur : si elle ne jette pas, la chaîne est une URL valide:

const isValidUrl = (string) => {
  try {
    new URL(string);
    return true;
  } catch (_) {
    return false;  
  }
}
25
répondu Pavlo 2017-04-18 08:22:24

pour valider L'Url en utilisant javascript est montré 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;
  }
}
23
répondu kavitha Reddy 2017-04-18 08:07:21

amélioration par rapport à la réponse acceptée...

  • A le double échappement des barres obliques inverses ( \ )
  • garantit que les domaines ont un point et une extension (.com .io .xyz)
  • permet le colon complet (:) dans le chemin par exemple http://thingiverse.com/download:1894343
  • permet ampersand (&) dans le chemin E. g 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('^(https?:\/\/)?'+ // 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);
    }
    
16
répondu TechyTimo 2017-10-26 22:59:57

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

import { isWebUri } from 'valid-url';
// ...
if (!isWebUri(url)) {
    return "Not a valid url.";
}
15
répondu Michael Bushe 2017-04-18 08:09:16

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

bien que l'utilisation d'URLs relatives de protocole n'est pas encouragée ( L'URL relative de protocole ), ils sont employés parfois. Pour valider une telle URL avec une expression régulière, la partie du protocole pourrait ê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 noté, l'expression régulière ne semble pas être le mieux adapté approche pour la validation d'Url.

8
répondu ko la 2018-04-25 03:13:08

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
7
répondu VicJordan 2018-04-17 02:26:58

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'));
6
répondu Ryan B 2018-04-18 22:24:17

Je ne peux pas commenter sur le post qui est le plus proche #5717133 , mais ci-dessous est la façon dont je compris comment obtenir @tom-gullen regex travailler.

/^(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
répondu chrisopedia 2017-05-23 11:55:19

comme il a été noté, le regex parfait est insaisissable mais semble quand même être une approche raisonnable (les alternatives sont les tests côté serveur ou la nouvelle expérience URL API ). Cependant, les réponses de haut niveau sont souvent retournant false pour des URLs communes, mais pire encore gèlera votre application / page pendant des minutes sur même une chaîne aussi simple que isURL('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa') . Il est indiqué dans certains commentaires, mais la plupart n'ont probablement pas saisi une mauvaise valeur pour le voir. Suspendu comme ça rend ce code inutilisable dans toute application sérieuse. Je pense que c'est dû à l'insensibilité répétée à la casse dans le code comme ((([a-z\d]([a-z\d-]*[a-z\d])*)\.?)+[a-z]{2,}|' ... . Prenez le " je " et il ne pend pas, mais bien sûr ne fonctionnera pas comme désiré. Mais même avec le drapeau ignorer cas ces tests rejettent des valeurs élevées unicode qui sont autorisés.

le meilleur déjà mentionné est:

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

Qui vient de Github segmentio/est-url . La bonne chose à propos d'un le dépôt de code est que vous pouvez voir le test et toutes les questions et aussi les chaînes de test qui s'y déroulent. Il y a une branche qui permettrait aux chaînes de caractères de manquer le protocole comme google.com , même si vous faites probablement trop d'hypothèses alors. le dépôt 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 peut être exploité pour les attaques DOS (Je ne pense pas que vous avez à vous inquiéter à ce sujet avec le client côté js, mais vous devez vous inquiéter de votre page pendant si longtemps que votre visiteur quitte votre site).

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

selon votre choix, lancez-le à travers cette fonction que j'ai adaptée des tests sur dperini/regex-weburl.js, en utilisant les outils de développement de votre navigateur inpector.

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:password@example.com:8080"));
console.assert(isURL("http://userid:password@example.com:8080/"));
console.assert(isURL("http://userid@example.com"));
console.assert(isURL("http://userid@example.com/"));
console.assert(isURL("http://userid@example.com:8080"));
console.assert(isURL("http://userid@example.com:8080/"));
console.assert(isURL("http://userid:password@example.com"));
console.assert(isURL("http://userid:password@example.com/"));
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:p@example.com:5702/db"));
console.assert(isURL("https://d1f4470da51b49289906b3d6cbd65074@app.getsentry.com/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 tester cette chaîne de 'a'.

voir ce comparaison du regex isURL par Mathias Bynens pour plus d'information avant de poster un regex apparemment grand.

5
répondu aamarks 2018-04-23 21:26:39

une fonction que j'ai utilisée pour valider une URL "string" est:

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

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

Cette fonction renvoie 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
3
répondu Chris 2018-04-22 21:53:49

vous pouvez utiliser l'API URL native API :

  const isUrl = string => {
      try { return Boolean(new URL(string)); }
      catch(e){ return false; }
  }
1
répondu Aral Roca 2018-03-14 17:05:56

la question demande une méthode de validation pour une url telle que stackoverflow , sans le protocole ni aucun point dans le nom d'hôte. Donc, il ne s'agit pas de valider l'url sintax, mais de vérifier si c'est une url valide, en l'appelant.

j'ai essayé plusieurs méthodes pour savoir si l'url true existe et est appelable depuis l'intérieur du navigateur, mais je n'ai pas trouvé de moyen de tester avec javascript l'en-tête de réponse de l'appel:

  • ajouter un élément d'ancrage est très bien pour tirer la méthode click() .
  • faire appel ajax à l'url provocante avec 'GET' est très bien, mais a ses diverses limitations dues aux politiques CORS et ce n'est pas le cas de l'utilisation de ajax , car l'url peut-être n'importe quel en dehors du domaine de mon serveur.
  • utilisant le fetch API a une solution similaire à ajax.
  • autre problème est que j'ai mon serveur sous le protocole https et lance une exception lors de l'appel d'urls non sécurisées.

donc, la meilleure solution que je puisse imaginer est d'obtenir un outil pour effectuer CURL en utilisant javascript essayant quelque chose comme curl -I <url> . Malheureusement je n'en ai pas trouvé et en apparence ce n'est pas possible. Je vous en seront reconnaissants des commentaires sur cette question.

mais, à la fin, j'ai un serveur tournant PHP et comme J'utilise Ajax pour presque tous mes requêtes, j'ai écrit une fonction du côté du serveur pour y exécuter la requête curl et retourner au navigateur.

en ce qui concerne l'url d'un seul mot sur la question "stackoverflow" , il me mènera à https://daniserver.com.ar/stackoverflow , où daniserver.com.ar est mon propre domaine.

1
répondu Daniel Faure 2018-04-22 17:49:46

je pense qu'utiliser l'API URL API est mieux qu'un motif regex complexe comme @pavlo l'a suggéré. Il a quelques inconvénients cependant que nous pouvons corriger par un certain 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 détecte pas non plus l'url incorrecte suivante.

http://w
http://..

alors pourquoi vérifier toute l'url? il nous suffit de vérifier domaine. j'ai emprunté le 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 pour cela aussi, et vous pouvez aussi ajouter un vérificateur D'adresse IP. J'aimerais m'en tenir à L'API native most, et espérer qu'elle commence à tout supporter dans un futur proche.

0
répondu Munim Munna 2018-04-16 22:11:09

Cela semble être l'un des plus difficiles problèmes de CS ;)

Voici une autre solution incomplète qui fonctionne assez bien pour moi et mieux que les autres que j'ai vu ici. J'utilise une entrée[type = url] pour cela afin de prendre en charge IE11, sinon ce serait beaucoup plus simple en utilisant 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:pw@mydomain.com'),
  validateUrl('https://google.com'),
  validateUrl('100.100.100.100/abc'),
  validateUrl('100.100.100.256/abc')); // false

afin d'accepter des intrants incomplets tels que "www.mydomain.com" il sera aussi le rendre valide en supposant que le protocole est "http" dans ces cas et en retournant L'URL valide si l'adresse est valide. Il retourne false lorsqu'il n'est pas valide.

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

0
répondu rosenfeld 2018-07-26 19:24:36