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
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;
}
}
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);
}
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"
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);
}
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;
}
}
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;
}
}
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); }
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.";
}
(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.
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
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'));
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
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.
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
vous pouvez utiliser l'API URL native API :
const isUrl = string => {
try { return Boolean(new URL(string)); }
catch(e){ return false; }
}
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 politiquesCORS
et ce n'est pas le cas de l'utilisation deajax
, 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.
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.
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.