¿Hay alguna manera en JavaScript para verificar si una cadena es una URL?
Las RegExes están excluidas porque la URL probablemente está escrita como stackoverflow
; es decir que podría no tener un .com
, www
o http
.
fuente
¿Hay alguna manera en JavaScript para verificar si una cadena es una URL?
Las RegExes están excluidas porque la URL probablemente está escrita como stackoverflow
; es decir que podría no tener un .com
, www
o http
.
Una pregunta relacionada con una respuesta:
Javascript regex coincidencia de URL
O este 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 locator
return !!pattern.test(str);
}
{ title: "Stackoverflow", uri: "http://stackoverflow.com" }
Actualización: de hecho, consulte code.google.com/chrome/extensions/bookmarks.html
invalid quantifier
. ¿Alguna idea?
SyntaxError: Invalid regular expression: /^(https?://)?((([a-zd]([a-zd-]*[a-zd])*).)+[a-z]{2,}|((d{1,3}.){3}d{1,3}))(:d+)?(/[-a-zd%_.~+]*)*(?[;&a-zd%_.~+=-]*)?(#[-a-zd_]*)?$/: Invalid group
Google Chrome (versión 30.0.1599.101) (Mac OS X: 10.8.5)
RegExp
, debe escapar dos veces de las barras invertidas; de lo contrario, obtendrá errores como un grupo no válido .
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);
}
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
start = new Date(); isURL("http://michalstefanow.com"); end = new Date(); diff = end - start; console.log(diff)
Puse una caldera, fui a un inodoro, llamé a mi madre y la cosa se hizo en ningún momento ...
true
por aaa
.
isURL('12345678901234567890123')
agregue algunos caracteres más y es aún peor.
Puede intentar usar el URL
constructor : si no se lanza, la cadena es una URL válida:
function isValidUrl(string) {
try {
new URL(string);
} catch (_) {
return false;
}
return true;
}
El término 'URL' se define en RFC 3886 (como URI); debe comenzar con un nombre de esquema, y el nombre del esquema no está limitado a http / https.
Ejemplos notables:
www.google.com
no es URL válida (esquema faltante)javascript:void(0)
es una URL válida, aunque no una HTTPhttp://..
Es URL válida, con el anfitrión bienestar ..
; si se resuelve depende de su DNShttps://google..com
es una URL válida, igual que la anteriorSi desea verificar si una cadena es una URL HTTP válida:
function isValidHttpUrl(string) {
let url;
try {
url = new URL(string);
} catch (_) {
return false;
}
return url.protocol === "http:" || url.protocol === "https:";
}
href
atributo para <a>
. La URL válida debe comenzar con un nombre de esquema , por ejemplo https://
.
isValidUrl("javascript:void(0)")
http://..
Ohttp:///a
En lugar de usar una expresión regular, recomendaría usar un elemento de anclaje.
cuando establece la href
propiedad de un anchor
, se establecen varias otras propiedades.
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"
Sin embargo, si el valor al que href
está vinculado no es una URL válida, entonces el valor de esas propiedades auxiliares será la cadena vacía.
Editar: como se señala en los comentarios: si se usa una URL no válida, las propiedades de la URL actual pueden ser sustituidas.
Por lo tanto, siempre que no pase la URL de la página actual, puede hacer algo como:
function isValidURL(str) {
var a = document.createElement('a');
a.href = str;
return (a.host && a.host != window.location.host);
}
a.href
no es válida, parser.host
devuelve el nombre de host de la página en la que se encuentra actualmente, no el esperado false
.
<a href="invalidurl">
, que no vaya a su dominio. Se agrega al final de la url actual. Entonces Chrome está haciendo lo correcto al darle el nombre de host actual del elemento "analizador".
function isValidURL(str)
: mucho mejor que usar regex! ¡Gracias!
Estoy usando la siguiente función para validar URL con o sin 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);
return (res !== null)
};
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
https://sdfasdp.ppppppppppp
decir, regresar, true
pero la mía regresa, lo false
que se espera, creo.
sadf@gmail.com
... ¿debería? Supongo que no debería
Para validar la URL usando javascript se muestra a continuación
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;
}
}
(http|https)
a (?:https?)
; b) :{0,1}
a :?
; c) [0-9]
a\d
Confíe en una biblioteca: https://www.npmjs.com/package/valid-url
import { isWebUri } from 'valid-url';
// ...
if (!isWebUri(url)) {
return "Not a valid url.";
}
{
en la url
Mejora en la respuesta aceptada ...
Permite el símbolo @ en la ruta, por ejemplo, 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);
}
Aquí hay otro método más.
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'));
new URL(string)
el código de Pavlo. Ambas pruebas tienen resultados idénticos con todos los casos límite que probé. Me gusta su código porque es más simple y no implica la creación de elementos, pero el tuyo es varias veces más rápido (probablemente porque no crea el el después del primer uso).
(No tengo representantes para comentar sobre el ejemplo de ValidURL ; por lo tanto, publique esto como respuesta).
Aunque no se recomienda el uso de protocolos URL relativas ( La dirección URL relativa al protocolo ), lo hacen llegar emplean a veces. Para validar dicha URL con una expresión regular, la parte del protocolo podría ser opcional, por ejemplo:
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;
}
}
Sin embargo, como otros señalaron, la expresión regular no parece ser el enfoque más adecuado para validar URL.
isValidURL("https://d1f4470da51b49289906b3d6cbd65074@app.getsentry.com/13176")
@
. No cuelga en mis navegadores .
Puede usar la API nativa de URL :
const isUrl = string => {
try { return Boolean(new URL(string)); }
catch(e){ return false; }
}
Como se ha señalado, la expresión regular perfecta es difícil de alcanzar pero parece ser un enfoque razonable (las alternativas son pruebas del lado del servidor o la nueva API de URL experimental ). Sin embargo, las respuestas de alto rango a menudo devuelven falsas para las URL comunes, pero aún peor congelarán su aplicación / página durante minutos en una cadena tan simple como isURL('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
. Se ha señalado en algunos de los comentarios, pero lo más probable es que no haya ingresado un valor malo para verlo. Colgar así hace que ese código sea inutilizable en cualquier aplicación seria. Creo que se debe a los conjuntos de mayúsculas y minúsculas repetidas en código como ((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|' ...
. Saque la 'i' y no se cuelga, pero por supuesto no funcionará como se desea. Pero incluso con el indicador de ignorar mayúsculas y minúsculas, esas pruebas rechazan valores altos de Unicode que están permitidos.
Lo mejor ya mencionado es:
function isURL(str) {
return /^(?:\w+:)?\/\/([^\s\.]+\.\S{2}|localhost[\:?\d]*)\S*$/.test(str);
}
Eso viene de Github segmento / is-url . Lo bueno de un repositorio de código es que puede ver las pruebas y cualquier problema y también las cadenas de prueba que se ejecutan a través de él. Hay una rama que permitiría que falten cadenas como el protocolo google.com
, aunque probablemente estés haciendo demasiados supuestos en ese momento. El repositorio se ha actualizado y no planeo tratar de mantener un espejo aquí. Se ha dividido en pruebas separadas para evitar rehacer RegEx que pueden explotarse para ataques DOS (no creo que tenga que preocuparse por eso con el lado del cliente js, pero sí tiene que preocuparse de que su página se cuelgue durante tanto tiempo que su el visitante abandona tu sitio).
Hay otro repositorio que he visto que puede ser incluso mejor para isURL en dperini / regex-weburl.js , pero es muy complejo. Tiene una lista de prueba más grande de URL válidas e inválidas. El simple anterior todavía pasa todos los positivos y solo falla al bloquear algunos negativos negativos http://a.b--c.de/
, así como los ips especiales.
Cualquiera que elija, ejecútelo a través de esta función que he adaptado de las pruebas en dperini / regex-weburl.js, mientras utiliza el inpector Herramientas de desarrollo de su navegador.
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"));}
Y luego prueba esa cadena de 'a's.
Consulte esta comparación de expresiones regulares isURL de Mathias Bynens para obtener más información antes de publicar una expresión regular aparentemente excelente.
isURL('a'.repeat(100))
millones de veces / segundo (la más compleja de dperini es en realidad más rápida). Algunas de las respuestas de alto rango del formulario ([a-zA-Z] +) * tardarían horas en completarse una vez. Busque redo RegEx para más información.
No puedo comentar sobre la publicación que es la más cercana # 5717133 , pero a continuación es la forma en que descubrí cómo hacer que @ tom-gullen regex funcione.
/^(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
var pattern = new RegExp('(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');
Use validator.js
ES6
import isURL from 'validator/lib/isURL'
isURL(string)
No ES6
var validator = require('validator');
validator.isURL(string)
También puede ajustar el comportamiento de esta función pasando un options
objeto opcional como el segundo argumento deisURL
Aquí está el options
objeto predeterminado :
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
y host_blacklist
pueden ser matrices de hosts. También admiten expresiones regulares.
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
Una función que he estado usando para validar una "cadena" de URL es:
var matcher = /^(?:\w+:)?\/\/([^\s\.]+\.\S{2}|localhost[\:?\d]*)\S*$/;
function isUrl(string){
return matcher.test(string);
}
Esta función devolverá un valor booleano si la cadena es una URL.
Ejemplos:
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
Esto es bastante difícil de hacer con regex puro porque las URL tienen muchos 'inconvenientes'.
Por ejemplo, los nombres de dominio tienen restricciones complicadas en guiones:
a. Se permite tener muchos guiones consecutivos en el medio.
si. pero el primer carácter y el último carácter del nombre de dominio no pueden ser un guión
C. Los caracteres tercero y cuarto no pueden ser ambos guiones
Del mismo modo, el número de puerto solo puede estar en el rango 1-65535. Esto es fácil de verificar si extrae la parte del puerto y la convierte, int
pero es bastante difícil de verificar con una expresión regular.
Tampoco hay una manera fácil de verificar extensiones de dominio válidas. Algunos países tienen dominios de segundo nivel (como 'co.uk'), o la extensión puede ser una palabra larga como '.international'. Y se agregan nuevos TLD regularmente. Este tipo de cosas solo se pueden verificar con una lista codificada. (ver https://en.wikipedia.org/wiki/Top-level_domain )
Luego están las direcciones URL de imanes, las direcciones ftp, etc. Todas tienen requisitos diferentes.
Sin embargo, aquí hay una función que maneja casi todo excepto:
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] + ']');
}
Creo que usar la API de URL nativa es mejor que los patrones complejos de expresiones regulares como sugirió @pavlo. Sin embargo, tiene algunos inconvenientes que podemos solucionar con algún código adicional. Este enfoque falla para la siguiente URL válida.
//cdn.google.com/script.js
Podemos agregar el protocolo faltante de antemano para evitarlo. Tampoco detecta la siguiente URL no válida.
http://w
http://..
Entonces, ¿por qué verificar toda la URL? solo podemos verificar el dominio. Tomé prestada la expresión regular para verificar el dominio desde aquí .
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;
}
}
El hostname
atributo es una cadena vacía para javascript:void(0)
, por lo que también funciona para eso, y también puede agregar un verificador de dirección IP. Me gustaría seguir con la API nativa, y espero que comience a admitir todo en un futuro próximo.
new URL
no tiene en las pruebas que he hecho. Esto es llamar: http://142.42.1.1 //false
y bloquear cadenas altas de Unicode.
La pregunta solicita un método de validación para una URL como stackoverflow
, sin el protocolo o ningún punto en el nombre de host. Por lo tanto, no se trata de validar sintaxis de URL, sino de verificar si es una URL válida, llamándola realmente.
Intenté varios métodos para saber si la url true existe y se puede llamar desde el navegador, pero no encontré ninguna forma de probar con javascript el encabezado de respuesta de la llamada:
click()
método.'GET'
está bien, pero tiene varias limitaciones debido a las CORS
políticas y no es el caso de usar ajax
, ya que la url puede estar fuera del dominio de mi servidor.https
protocolo y produce una excepción al llamar a URL no seguras.Entonces, la mejor solución que se me ocurre es obtener alguna herramienta para realizar CURL
usando JavaScript intentando algo como curl -I <url>
. Lamentablemente no encontré ninguno y aparentemente no es posible. Agradeceré cualquier comentario sobre esto.
Pero, al final, tengo un servidor ejecutándose PHP
y, como uso Ajax para casi todas mis solicitudes, escribí una función en el lado del servidor para realizar la solicitud de curl allí y volver al navegador.
Con respecto a la url de una sola palabra en la pregunta 'stackoverflow', me llevará a https://daniserver.com.ar/stackoverflow
donde daniserver.com.ar es mi propio dominio.
foo
y asumir que es http o https o .com o .es o cualquiera de los innumerables sufijos? ¿Sigues tirando el fregadero de la cocina hasta que te vuelves verdadero?
Este parece ser uno de los problemas más difíciles en CS;)
Aquí hay otra solución incompleta que funciona lo suficientemente bien para mí y mejor que las otras que he visto aquí. Estoy usando una entrada [type = url] para esto para soportar IE11, de lo contrario sería mucho más simple usar window.URL para realizar la validación en su lugar:
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
Para aceptar entradas incompletas como "www.midominio.com", también será válido suponiendo que el protocolo es "http" en esos casos y devolverá la URL válida si la dirección es válida. Devuelve falso cuando no es válido.
También admite dominios IPv4, pero no IPv6.
En mi caso, mi único requisito es que la entrada del usuario no se interpretará como un enlace relativo cuando se coloca en el href de una etiqueta y las respuestas aquí fueron un poco OTT para eso o URL permitidas que no cumplen mis requisitos, por lo que esto es con lo que voy:
^https?://.+$
Lo mismo podría lograrse con bastante facilidad sin expresiones regulares.
esta trabajando conmigo
function isURL(str) {
var regex = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/;
var pattern = new RegExp(regex);
return pattern.test(str);
}
Si puede cambiar el tipo de entrada, creo que esta solución sería mucho más fácil:
Puede usarlo simplemente type="url"
en su entrada y verificarlo checkValidity()
en js
P.ej:
your.html
<input id="foo" type="url">
your.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
}
});
Este definitivamente no es el enfoque más efectivo, pero es legible y fácil de adaptar a lo que necesite. Y es más fácil agregar expresiones regulares / complejidad desde aquí. Así que aquí hay un enfoque muy pragmático
const validFirstBits = ["ftp://", "http://", "https://", "www."];
const invalidPatterns = [" ", "//.", ".."];
export function isUrl(word) {
// less than www.1.dk
if (!word || word.length < 8) return false;
// Let's check and see, if our candidate starts with some of our valid first bits
const firstBitIsValid = validFirstBits.some(bit => word.indexOf(bit) === 0);
if (!firstBitIsValid) return false;
const hasInvalidPatterns = invalidPatterns.some(
pattern => word.indexOf(pattern) !== -1,
);
if (hasInvalidPatterns) return false;
const dotSplit = word.split(".");
if (dotSplit.length > 1) {
const lastBit = dotSplit.pop(); // string or undefined
if (!lastBit) return false;
const length = lastBit.length;
const lastBitIsValid =
length > 1 || (length === 1 && !isNaN(parseInt(lastBit)));
return !!lastBitIsValid;
}
return false;
}
PRUEBA:
import { isUrl } from "./foo";
describe("Foo", () => {
test("should validate correct urls correctly", function() {
const validUrls = [
"http://example.com",
"http://example.com/blah",
"http://127.0.0.1",
"http://127.0.0.1/wow",
"https://example.com",
"https://example.com/blah",
"https://127.0.0.1:1234",
"ftp://example.com",
"ftp://example.com/blah",
"ftp://127.0.0.1",
"www.example.com",
"www.example.com/blah",
];
validUrls.forEach(url => {
expect(isUrl(url) && url).toEqual(url);
});
});
test("should validate invalid urls correctly", function() {
const inValidUrls = [
"http:// foo.com",
"http:/foo.com",
"http://.foo.com",
"http://foo..com",
"http://.com",
"http://foo",
"http://foo.c",
];
inValidUrls.forEach(url => {
expect(!isUrl(url) && url).toEqual(url);
});
});
});
Mathias Bynens ha compilado una lista de expresiones regulares de URL conocidas con URL de prueba. Hay pocas razones para escribir una nueva expresión regular; simplemente elija uno existente que más le convenga.
Pero la tabla de comparación para esas expresiones regulares también muestra que es casi imposible hacer la validación de URL con una sola expresión regular. Todas las expresiones regulares en la lista de Bynens producen falsos positivos y falsos negativos.
Le sugiero que use un analizador de URL existente (por ejemplo new URL('http://www.example.com/')
en JavaScript) y luego aplique las comprobaciones que desea realizar en la forma analizada y normalizada de la URL resp. sus componentes El uso de la URL
interfaz de JavaScript tiene el beneficio adicional de que solo aceptará las URL que el navegador realmente acepte.
También debe tener en cuenta que las URL técnicamente incorrectas aún pueden funcionar. Por ejemplo http://w_w_w.example.com/
, http://www..example.com/
, http://123.example.com/
todos tienen una parte de host no válido, pero todos los navegadores sé que van a tratar de abrirlos sin quejas, y cuando se especifique las direcciones IP de esos nombres no válidos en/etc/hosts/
tales direcciones URL incluso trabajar, pero sólo en su ordenador.
Por lo tanto, la pregunta no es tanto si una URL es válida, sino qué URL funcionan y deberían permitirse en un contexto particular.
Si desea realizar la validación de URL, hay muchos detalles y casos extremos que son fáciles de pasar por alto:
http://user:password@www.example.com/
.http://www.stackoverflow.com.
).[-0-9a-zA-z]
definitivamente ya no es suficiente.co.uk
y muchos otros).Cuál de estas limitaciones y reglas se aplica es una cuestión de requisitos y gustos del proyecto.
Recientemente escribí un validador de URL para una aplicación web que es adecuada para URL proporcionadas por el usuario en foros, redes sociales o similares. Siéntase libre de usarlo como base para su propio:
También he escrito una publicación de blog The Gory Details of URL Validation con información más detallada.
Cambio la función a Match + y hago un cambio aquí con las barras y su trabajo: (http: // y https) ambos
function isValidUrl(userInput) {
var res = userInput.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;
}
Aquí hay una comprobación muy simple para asegurarse de que haya un protocolo válido y que la extensión del dominio debe tener dos o más caracteres.
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
);
};
Si necesita soporte también https://localhost:3000
, utilice esta versión modificada de la expresión regular de [Devshed].
function isURL(url) {
if(!url) return false;
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
'localhost' + // OR localhost
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
'(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
'(\\#[-a-z\\d_]*)?$', 'i'); // fragment locator
return pattern.test(url);
}
Hay un par de pruebas que usan el constructor de URL que no delinean si la entrada es una cadena o un objeto de URL.
// Testing whether something is a URL
function isURL(url) {
return toString.call(url) === "[object URL]";
}
// Testing whether the input is both a string and valid url:
function isUrl(url) {
try {
return toString.call(url) === "[object String]" && !!(new URL(url));
} catch (_) {
return false;
}
}
Actualización 2020. Para ampliar las excelentes respuestas de @iamnewton y @Fernando Chavez Herrera, he comenzado a ver que @
se utilizan en la ruta de las URL.
Entonces la expresión regular actualizada es:
RegExp('(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');
Si desea permitirlo en la cadena de consulta y el hash, use:
RegExp('(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');
Dicho esto, no estoy seguro de si hay una regla de documento técnico que no se permita @
en la cadena de consulta o hash.
Ya hay muchas respuestas, pero aquí hay otra contribución: tomada directamente de la URL
verificación de validez de polyfill, use un input
elemento con type="url"
para aprovechar la verificación de validez incorporada en el navegador:
var inputElement = doc.createElement('input');
inputElement.type = 'url';
inputElement.value = url;
if (!inputElement.checkValidity()) {
throw new TypeError('Invalid URL');
}
http
, por defecto no hay url.<scheme>:<scheme-specific-part>
href
elemento de anclaje, funciona al llamarwindow.open(url)
, señala algo que realmente existe, funciona en la ubicación del navegador barra, o una combinación de lo anterior? Obtendrá respuestas muy diferentes según cuál de estas le interese.