Verificați dacă un șir JavaScript este un URL (Programare, Javascript, String, Url)

Bruno a intrebat.

Există o modalitate în JavaScript de a verifica dacă un șir de caractere este un URL?

RegEx-urile sunt excluse deoarece URL-ul este cel mai probabil scris astfel stackoverflow; adică s-ar putea să nu aibă un .com, www sau http.

Comentarii

    26

  • Dacă îi lipsește http, este implicit fără adresă URL. –  > Por nfechner.
  • @nfechner adică dacă nu specifică un protocol și nu folosește caracterul două puncte (de preferință cu două barete înainte alături) atunci nu este un URL? –  > Por jcolebrand.
  • După cum puteți citi în URL RFC, singura parte necesară pentru ca un șir de caractere să devină un URL valid este cea cu două puncte. URL-urile valide arată astfel: <scheme>:<scheme-specific-part> –  > Por nfechner.
  • a se vedea stackoverflow.com/a/3975573/572180 –  > Por nguyên.
  • Modul în care se testează dacă ceva este un URL este foarte mult dependentă de context și prea vagă fără o calificare suplimentară. Contează pentru tine dacă este conform cu specificația URL RFC, dacă funcționează atunci când se face un apel de sistem OS pentru a deschide URL-ul, dacă se analizează ca un href într-un element de ancorare, funcționează atunci când se apelează window.open(url), indică ceva care există cu adevărat, funcționează în bara de localizare a browserului sau o combinație a celor de mai sus? Veți primi răspunsuri foarte diferite în funcție de care dintre acestea vă interesează. –  > Por Roy Tinker.
31 răspunsuri
Tom Gullen

O întrebare conexă cu un răspuns:

Javascript regex de potrivire URL

Sau acest Regexp de la 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);
}

Comentarii

  • @Bruno: este foarte probabil ca acestea să fie salvate intern cu titluri și URL-uri separate, cum ar fi { title: "Stackoverflow", uri: "http://stackoverflow.com" } Actualizare: într-adevăr, a se vedea code.google.com/chrome/extensions/bookmarks.html –  > Por Marcel Korpel.
  • încerc să folosesc exemplul dumneavoastră. Dar primesc o eroare pe firebug care spune că invalid quantifier. Aveți vreo idee? –  > Por Sisir.
  • 127

  • Funcția returnează: 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 (Versiunea 30.0.1599.101) (Mac OS X: 10.8.5) –  > Por dr.dimitru.
  • Rețineți că dacă folosiți un șir de caractere ca parametru pentru funcția RegExp trebuie să scăpați de două ori backslash-urile – altfel veți obține erori de genul grup invalid. –  > Por Kjell.
  • Cu Firefox 52.0.2, testarea cu șiruri de caractere „lungi” (de fapt, nu atât de lungi, 40 de caractere sunt suficiente) este incredibil de lentă, până la punctul în care trebuie să opresc scriptul. Nu știu dacă este un bug Firefox sau ceva în neregulă cu expresia în sine. –  > Por youen.
Pavlo

Dacă doriți să verificați dacă un șir de caractere este un URL HTTP valid, puteți utiliza URL constructor (acesta va arunca în cazul unui șir de caractere malformat):

function isValidHttpUrl(string) {
  let url;
  
  try {
    url = new URL(string);
  } catch (_) {
    return false;  
  }

  return url.protocol === "http:" || url.protocol === "https:";
}

Rețineți că per RFC 3886, URL-ul trebuie să înceapă cu o schemă (nu se limitează la http/https), de ex:

  • www.example.com nu este un URL valid (lipsește schema)
  • javascript:void(0) este un URL valid, deși nu este un URL HTTP
  • http://.. este o adresă URL validă, cu gazdă .. (dacă se rezolvă sau nu depinde de DNS-ul dumneavoastră)
  • https://example..com este un URL valid, la fel ca mai sus

Comentarii

    15

  • @AshD nu, nu este; de exemplu, nu puteți utiliza ca href pentru <a>. URL valabil trebuie să înceapă cu un nume de schemă, de ex. https://. –  > Por Pavlo.
  • new URL(‘javascript:alert(23)’) –  > Por blade091.
  • @Pavlo acest lucru returnează adevărat isValidUrl("javascript:void(0)") –  > Por Praveena.
  • Îmi place acest lucru pentru că mă învață lucruri noi despre js! Nu are niciun fals negativ pe care l-am putut găsi. Are câteva falsuri pozitive: http://.. Sau http:///a –  > Por aamarks.
  • URL-ul funcționează începând de la Edge, așa că tot ce este mai jos s-ar putea să nu funcționeze așa cum vă așteptați. Asigurați-vă că verificați mai întâi compatibilitatea. –  > Por Tony T..
Zemljoradnik
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);
}

Comentarii

    16

  • nu reușește pentru linkurile de imagine din Google Search : 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 –  > Por bill davis.
  • acest lucru este inutilizabil lent –  > Por Hernán Eche.
  • @HernánEche Ce vrei să spui prin lent? start = new Date(); isURL("http://michalstefanow.com"); end = new Date(); diff = end - start; console.log(diff) Am pus un ceainic pe foc, m-am dus la o toaletă, am sunat-o pe mama și chestia a fost gata în cel mai scurt timp… –  > Por Mars Robertson.
  • 64

  • Se întoarce true pentru aaa. –  > Por alex naumov.
  • Acesta nu ar trebui să fie absolut deloc răspunsul corect. Nu reușește multe cazuri de testare și, mai important, vă blochează pagina chiar și pe un șir scurt: isURL('12345678901234567890123') dacă mai adăugați câteva caractere, este chiar mai rău. –  > Por aamarks.
Luke

Mai degrabă decât să folosiți o expresie regulată, v-aș recomanda să folosiți un element de ancorare.

Atunci când setați elementul href a unui element anchor, sunt setate diverse alte proprietăți.

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"

sursa

Cu toate acestea, dacă valoarea href la care este legată nu este o adresă URL validă, atunci valoarea acestor proprietăți auxiliare va fi șirul gol.

Editați: așa cum s-a subliniat în comentarii: dacă se utilizează un URL invalid, proprietățile URL-ului curent pot fi substituite.

Deci, atâta timp cât nu treceți URL-ul paginii curente, puteți face ceva de genul:

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

Comentarii

  • Acesta nu este cazul (cel puțin în Chrome 48). Dacă adresa URL transmisă către a.href este invalidă, parser.host returnează numele de gazdă al paginii pe care vă aflați în prezent, nu adresa așteptată false. –  > Por Sam Beckham.
  • Ce ciudat! Jur că am testat asta! Cred că este corect să spunem că acest lucru nu va trebui să fie folosit vreodată pe pagina curentă, astfel încât condiționalul poate fi schimbat. Voi edita postul. –  > Por Luke.
  • nu este un caz de utilizare foarte tipic, dar această tehnică nu funcționează în contextul ferestrei browserului Firefox (important pentru dezvoltarea de addon-uri) –  > Por chrmod.
  • function isValidURL(str): mult mai bine decât utilizarea regex-ului! Vă mulțumim! –  > Por Rodrigo.
  • O modalitate destul de simplă de a ocoli problema. Aceste proprietăți sunt totuși experimentale: developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement –  > Por Boris D. Teoharov.
Vikasdeep Singh

Folosesc funcția de mai jos pentru a valida URL-ul cu sau fără http/https:

Comentarii

  • Pare o soluție bună! Ați putea adăuga câteva teste care să arate că funcționează în unele cazuri colțoase (vezi de exemplu aceste comentarii)? –  > Por Basj.
  • @Basj a adăugat cazuri de testare. Vă rugăm să verificați –  > Por Vikasdeep Singh.
  • Nu este rău, nu reușește să treacă http://⌘.ws sau 142.42.1.1 și permite http://.www.foo.bar./, dar nu se blochează ca unele dintre celelalte regex-uri, inclusiv cele mai bine cotate răspunsuri. –  > Por aamarks.
  • @aamarks Am verificat răspunsul tău. Răspunsul dvs. eșuează pentru https://sdfasdp.ppppppppppp adică returnează true dar al meu returnează false ceea ce cred că este de așteptat. –  > Por Vikasdeep Singh.
  • se întoarce adevărat pentru [email protected]…ar trebui? Cred că nu ar trebui.  > Por Zohab Ali.
kavitha Reddy

Pentru a valida Url folosind javascript este prezentat mai jos

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;
  }
}

Comentarii

  • Mai multe părți ale regex-ului ar putea fi reduse foarte mult: a) (http|https) la (?:https?); b) :{0,1} la :?; c) [0-9] la d –  > Por Dima Parzhitsky.
Michael Bushe

Bazează-te pe o bibliotecă:https://www.npmjs.com/package/valid-url

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

Comentarii

  • aceasta îmi dă multe probleme cu urls ciudate care sunt de fapt analizate de browser, de exemplu: având un { în url –  > Por Willyfrog.
Mwirabua Tim

Îmbunătățire a răspunsului acceptat…

  • Verificați dacă există ftp/ftps ca protocol
  • Are scăpare dublă pentru backslash-uri (\)
  • Asigură că domeniile au un punct și o extensie (.com .io .xyz)
  • Permite două puncte (:) în calea de acces, de ex. http://thingiverse.com/download:1894343
  • Permite ampersandă (&) în calea de acces, de exemplu http://en.wikipedia.org/wiki/Procter_&_Gamble
  • Permite simbolul @ în calea de acces, de ex. 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);
    }
    

Comentarii

  • Nu, nu ar trebui să fie răspunsul acceptat. La fel ca și altele, se bazează pe un simplu șir de 33 de caractere: isURL(‘123456789012345678901234567890123’) și nu reușește să treacă multe teste de caz limită: foo.com/blah_blah_(wikipedia)_(din nou) //întoarce în mod incorect false. –  > Por aamarks.
  • Acest lucru se datorează faptului că localhost:8080 nu este un URL valid. –  > Por Shane.
  • Exemplu de lucru: runkit.com/shanekenyon87/5bc0e57263c77b0012db05dc –  > Por Shane.
  • Ar trebui să fie ftps://localhost:8080 =) –  > Por vp_arth.
  • Nu pare să funcționeze: se blochează la intrări lungi (cum a spus @aanmarks) –  > Por cecemel.
Ryan Breece

Iată încă o metodă.

Comentarii

  • Cod educațional! Mecanismul de aici este probabil identic cu modul în care new URL(string) funcționează în codul lui Pavlo. Ambele teste au rezultate identice cu toate cazurile limită pe care le-am testat. Îmi place codul lui pentru că este mai simplu și nu implică crearea de elemente, dar al tău este de câteva ori mai rapid (probabil pentru că nu creează el după prima utilizare). –  > Por aamarks.
  • Vă mulțumesc! Am pus în aplicare sfatul tău. Fiți atenți însă: Browserele mai vechi și/sau dispozitivele mobile WebView pot să nu fi implementat elementul <input type =url> astfel, valoarea de intrare ar fi tratată ca un text obișnuit (fără validare URL). REF: developer.mozilla.org/en-US/docs/Web/HTML/Element/input/url –  > Por Panini Luncher.
ko la

(Nu am reprize pentru a comenta exemplul ValidURL; prin urmare, postați asta ca răspuns).

În timp ce utilizarea URL-urilor relative la protocol nu este încurajată (URL-ul relativ la protocol), acestea sunt folosite uneori. Pentru a valida un astfel de URL cu o expresie regulată, partea de protocol ar putea fi opțională, de ex:

function isValidURL(str) {
    var pattern = new RegExp('^((https?:)?\/\/)?'+ // protocol
        '(?:\S+(?::\S*)[email protected])?' + // 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;
    }
}

După cum au remarcat și alții, expresia regulată nu pare a fi totuși cea mai potrivită abordare pentru validarea URL-urilor.

Comentarii

  • La început am crezut că acest lucru este destul de bun, dar nu reușește multe dintre testele de la mathiasbynens.be/demo/url-regex, și apoi se blochează la isValidURL("https://[email protected]/13176") –  > Por aamarks.
  • Da, așa cum am spus, am comentat doar partea de protocol. Am adăugat clauza de autentificare pentru a gestiona @. Nu se blochează în browsere. –  > Por ko la.
  • Scuze, am trecut prin mai multe dintre acestea pentru a le evalua și am ratat faptul că al tău comenta răspunsul dat. Cred că corecția ta chiar m-a ajutat să mă apuc de acestea când am vizitat prima dată această pagină. Nu mai atârnă acum. –  > Por aamarks.
Aral Roca

Puteți folosi API nativ URL:

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

Comentarii

  • Seamănă foarte mult cu răspunsul oferit de @pavlo, doar numele variabilelor au fost schimbate 😉 –  > Por Munim Munna.
  • ar trebui să existe într-adevăr o metodă nativă simplă pentru a verifica acest lucru până acum – acest răspuns părea foarte promițător, dar returnează true devreme, așa cum a menționat @Basj mai sus. –  > Por zero_cool.
aamarks

După cum a fost observat, regexul perfect este evaziv, dar pare a fi încă o abordare rezonabilă (alternativele sunt testele de pe server sau noul experimental URL API). Cu toate acestea, răspunsurile de rang înalt returnează adesea răspunsuri false pentru URL-uri comune, dar și mai rău, vă vor bloca aplicația/pagina timp de câteva minute chiar și pentru un simplu șir de caractere precum isURL('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'). Acest lucru a fost subliniat în unele dintre comentarii, dar majoritatea probabil că nu au introdus o valoare rea pentru a o vedea. O astfel de suspendare face ca acest cod să fie inutilizabil în orice aplicație serioasă. Cred că se datorează seturilor repetate care nu țin cont de majuscule și minuscule în coduri precum ((([a-z\d]([a-z\d-]*[a-z\d])*)\.?)+[a-z]{2,}|' .... Scoateți „i” și nu se blochează, dar, desigur, nu va funcționa așa cum se dorește. Dar chiar și cu stegulețul de ignorare a cazurilor, aceste teste resping valorile unicode ridicate care sunt permise.

Cel mai bun deja menționat este:

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

Acesta provine de pe Github segmentio/is-url. Lucrul bun la un depozit de cod este că puteți vedea testele și orice probleme și, de asemenea, șirurile de testare rulate prin el. Există o ramură care ar permite ca șirurile care lipsesc protocolul ca google.com, deși probabil că faci prea multe presupuneri în acest caz. Depozitul a fost actualizat și nu intenționez să încerc să păstrez o oglindă aici. A fost împărțit în teste separate pentru a evita RegEx redos care pot fi exploatate pentru atacuri DOS (nu cred că trebuie să vă faceți griji pentru asta cu client side js, dar trebuie să vă faceți griji pentru că pagina dvs. să stea atâta timp încât vizitatorul dvs. să părăsească site-ul).

Există un alt depozit pe care l-am văzut că poate fi chiar mai bun pentru isURL la dperini/regex-weburl.js, dar este foarte complex. Are o listă de testare mai mare de URL-uri valide și invalide. Cel simplu de mai sus încă trece toate cele pozitive și nu reușește să blocheze decât câteva negative ciudate, cum ar fi http://a.b--c.de/ precum și ips-urile speciale.

Oricare ați alege, rulați-o prin această funcție pe care am adaptat-o din testele de pe dperini/regex-weburl.js, în timp ce utilizați inpectorul Developer Tools al browserului dumneavoastră.

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"));}

Și apoi testați acel șir de „a-uri”.

Vedeți acest lucru comparație a regex-ului isURL de Mathias Bynens pentru mai multe informații înainte de a posta un regex aparent grozav.

Comentarii

  • Am verificat răspunsul tău. Răspunsul dvs. eșuează pentru sdfasdp.ppppppppppppppppppppp adică returnează true, dar se așteaptă să fie false –  > Por Vikasdeep Singh.
  • Cred că este un URL valid, din punct de vedere structural. Nu sunt un expert în materie de standard, dar nu cred că există o limită de lungime a porțiunii .com (știu că .online este legal). –  > Por aamarks.
  • Abia dacă știam să scriu un regex acum câteva luni. Problema este gravă. Ambele regex-uri pe care le-am citat pot completa isURL('a'.repeat(100)) milioane de ori/sec (cel mai complex de la dperini este de fapt mai rapid). Unele dintre răspunsurile de rang înalt de forma ([a-zA-Z]+)*)* ar dura ore întregi pentru a se finaliza o singură dată. Căutați RegEx redos pentru mai multe informații. –  > Por aamarks.
iamnewton

Nu pot să comentez pe postul care este cel mai apropiat #5717133, dar mai jos este modul în care mi-am dat seama cum să fac să funcționeze @tom-gullen regex-ul.

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

Comentarii

  • Acest lucru a funcționat pentru mine, dar am avut nevoie de backslash-uri backslash-uri. 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'); –  > Por Fernando Chavez Herrera.
  • Verificați w3resource.com/javascript-exercises/… pentru mai multe cazuri de testare –  > Por Kewal Shah.
Chris

O funcție pe care am folosit-o pentru a valida un „șir” URL este:

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

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

Această funcție va returna un boolean dacă șirul este un URL.

Exemple:

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

Ilyich

Utilizați validator.js

ES6

import isURL from 'validator/lib/isURL'

isURL(string)

Fără ES6

var validator = require('validator');

validator.isURL(string)

Puteți, de asemenea, să reglați cu precizie comportamentul acestei funcții prin trecerea opționalelor options ca al doilea argument al funcției isURL

Aici este valoarea implicită options obiect:

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 și host_blacklist pot fi rețele de gazde. De asemenea, acestea acceptă expresii regulate.

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

Comentarii

  • Frumos! Bibliotecă mică (mai puțin de 40k minificate), bibliotecă populară (peste 3 milioane de descărcări săptămânale pe npm), vă oferă tone de flexibilitate în ceea ce privește specificarea validității URL-urilor pentru cazul dvs. particular de utilizare și are o serie de alți validatori în afară de URL. Acesta este, de departe, cel mai bun răspuns, IMHO. –  > Por Javid Jamae.
  • Frumoasă bibliotecă. Poate valida URL-uri, dar și multe alte lucruri. –  > Por Bemipefe.
Caner

Acest lucru este destul de dificil de făcut cu regexul pur, deoarece URL-urile au multe „inconveniente”.

  1. De exemplu, numele de domeniu au restricții complicate în ceea ce privește cratimele:

    a. Este permisă existența mai multor cratime consecutive la mijloc.

    b. dar primul caracter și ultimul caracter al numelui de domeniu nu pot fi o cratimă

    c. Al 3-lea și al 4-lea caracter nu pot fi ambele cratimă

  2. În mod similar, numărul de port poate fi numai în intervalul 1-65535. Acest lucru este ușor de verificat dacă extrageți partea de port și o convertiți în int dar este destul de dificil de verificat cu o expresie regulată.

  3. De asemenea, nu există o modalitate ușoară de a verifica extensiile de domeniu valide. Unele țări au domenii de al doilea nivel(cum ar fi „co.uk”), sau extensia poate fi un cuvânt lung, cum ar fi „.international”. Iar noi TLD-uri sunt adăugate în mod regulat. Acest tip de lucruri poate fi verificat doar în funcție de o listă codificată. (a se vedea https://en.wikipedia.org/wiki/Top-level_domain)

  4. Apoi, există urile magnet, adresele ftp etc. Toate acestea au cerințe diferite.

Cu toate acestea, iată o funcție care se ocupă cam de toate, cu excepția:

  • Cazul 1. c.
  • Acceptă orice număr de port de 1-5 cifre
  • Acceptă orice extensie de 2-13 caractere
  • Nu acceptă ftp, magnet, etc…

Bruno Finger

Există deja o mulțime de răspunsuri, dar iată o altă contribuție: Preluat direct de pe URL verificarea validității polyfill, utilizați un input cu type="url" pentru a profita de verificarea validității încorporată în browser:

var inputElement = doc.createElement('input');
inputElement.type = 'url';
inputElement.value = url;

if (!inputElement.checkValidity()) {
    throw new TypeError('Invalid URL');
}

Sursa

Crashalot

Această funcție nu permite localhost și permite doar URL-uri pentru pagini web (adică permite doar protocolul http sau https).

De asemenea, permite doar caracterele sigure, așa cum sunt definite aici: https://www.urlencoder.io/learn/

function isValidWebUrl(url) {
   let regEx = /^https?://(?:www.)?[[email protected]:%._+~#=]{1,256}.[a-zA-Z0-9()]{1,6}b([-a-zA-Z0-9()@:%_+.~#?&//=]*)$/gm;
   return regEx.test(url);
}

HeshamSalama

acest lucru funcționează cu mine

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

Comentarii

  • Acest răspuns a fost deja dat mai sus cu 4 ani în urmă de kavitha Reddy. –  > Por aamarks.
  • Am făcut-o mai simplă și mai abstractă –  > Por HeshamSalama.
Daniel Rodríguez

Dacă puteți schimba tipul de intrare, cred că această soluție ar fi mult mai ușoară:

Puteți folosi pur și simplu type="url" în intrare, iar verificarea să se facă cu checkValidity() în js

De ex:

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
    }
});

Guido Flohr

Mathias Bynens a compilat o listă de binecunoscute regexuri URL cu URL-uri de test. Nu există prea multe motive pentru a scrie o nouă expresie regulată; alegeți doar una existentă care vi se potrivește cel mai bine.

Dar tabelul de comparație pentru aceste expresii regulate arată, de asemenea, că este aproape imposibil să faci validarea URL-urilor cu o singură expresie regulată. Toate regexurile din lista lui Bynens produc falsuri pozitive și false negative.

Vă sugerez să folosiți un analizor URL existent (de exemplu new URL('http://www.example.com/') în JavaScript) și apoi să aplicați verificările pe care doriți să le efectuați față de forma analizată și normalizată a URL-ului resp. a componentelor sale. Folosind JavaScript URL are avantajul suplimentar că va accepta numai astfel de URL-uri care sunt într-adevăr acceptate de browser.

De asemenea, trebuie să țineți cont de faptul că URL-urile incorecte din punct de vedere tehnic pot funcționa în continuare. De exemplu http://w_w_w.example.com/, http://www..example.com/, http://123.example.com/ au toate o parte de nume de gazdă invalidă, dar fiecare browser pe care îl cunosc va încerca să le deschidă fără să se plângă, iar atunci când specificați adrese IP pentru aceste nume invalide în /etc/hosts/ astfel de URL-uri chiar vor funcționa, dar numai pe computerul dumneavoastră.

Prin urmare, întrebarea nu este atât de mult dacă un URL este valid, ci mai degrabă care sunt URL-urile care funcționează și care ar trebui să fie permise într-un anumit context.

Dacă doriți să faceți validarea URL-urilor, există o mulțime de detalii și cazuri limită care sunt ușor de trecut cu vederea:

  • URL-urile pot conține credențiale, ca în http://user:[email protected]/.
  • Numerele de port trebuie să fie în intervalul 0-65535, dar este posibil să doriți totuși să excludeți portul joker 0.
  • Numerele de porturi pot avea zerouri la început, ca în http://www.example.com:000080/.
  • Adresele IPv4 nu sunt în niciun caz limitate la 4 numere întregi zecimale în intervalul 0-255. Puteți utiliza de la unul la patru numere întregi, iar acestea pot fi zecimale, octale sau hexazecimale. URL-urile https://010.010.000010.010/, https://0x8.0x8.0x0008.0x8/, https://8.8.2056/, https://8.526344/, https://134744072/ sunt toate valide și sunt doar moduri creative de a scrie https://8.8.8.8/.
  • Permiterea adreselor loopback (http://127.0.0.1/), adrese IP private (http://192.168.1.1), adrese link-local (http://169.254.100.200) și așa mai departe pot avea un impact asupra securității sau confidențialității. Dacă, de exemplu, le permiteți ca adrese ale avatarurilor utilizatorilor pe un forum, faceți ca browserele utilizatorilor să trimită cereri de rețea nesolicitate în rețeaua lor locală, iar în internetul lucrurilor, astfel de cereri pot provoca lucruri amuzante și mai puțin amuzante în casa dumneavoastră.
  • Din aceleași motive, este posibil să doriți să eliminați linkurile către nume de gazdă care nu sunt complet calificate, cu alte cuvinte nume de gazdă fără punct.
  • Dar numele de gazdă pot avea întotdeauna un punct la sfârșit (ca în http://www.stackoverflow.com.).
  • Partea de nume de gazdă a unui link poate conține paranteze unghiulare pentru adresele IPv6, ca în http://[::1].
  • Adresele IPv6 au, de asemenea, intervale pentru rețelele private sau adrese link-local etc.
  • Dacă blocați anumite adrese IPv4, țineți cont de faptul că, de exemplu https://127.0.0.1 și https://[::ffff:127.0.0.1] indică aceeași resursă (dacă dispozitivul loopback al mașinii dvs. este pregătit pentru IPv6).
  • Porțiunea de nume de gazdă a URL-urilor poate conține acum Unicode, astfel încât intervalul de caractere [-0-9a-zA-z] nu mai este cu siguranță suficient.
  • Multe registre pentru domeniile de nivel superior definesc restricții specifice, de exemplu cu privire la setul de caractere Unicode permise. Sau își subdivizează spațiul de nume (cum ar fi co.uk și multe altele).
  • Domeniile de nivel superior nu trebuie să conțină cifre zecimale, iar cratima nu este permisă decât pentru prefixul IDN A-label „xn--„.
  • Domeniile de nivel superior Unicode (și codificarea lor punycode cu „xn--„) trebuie să conțină în continuare numai litere, dar cine vrea să verifice acest lucru într-un regex?

Care dintre aceste limitări și reguli se aplică este o chestiune care ține de cerințele și gustul proiectului.

Am scris recent un validator de URL-uri pentru o aplicație web care este potrivit pentru URL-uri furnizate de utilizatori în forumuri, rețele sociale sau altele asemenea. Nu ezitați să îl folosiți ca bază pentru unul propriu:

Am scris, de asemenea, un articol pe blog Detaliile sângeroase ale validării URL-urilor cu informații mai detaliate.

Ashish Gupta

Am schimbat funcția în Match + fac o schimbare aici cu slash-urile și munca sa: (http:// și https) atât

function isValidUrl(userInput) {
    var res = userInput.match(/(http(s)?://.)?(www.)?[[email protected]:%._+~#=]{2,256}.[a-z]{2,6}b([[email protected]:%_+.~#?&//=]*)/g);
    if(res == null)
       return false;
    else
       return true;
}

Comentarii

  • În 2021, acest lucru a funcționat pentru mine în toate configurațiile URL –  > Por James Stewart.
Munim Munna

Cred că folosind aplicația nativă API URL este mai bună decât un model regex complex, așa cum a sugerat @pavlo. Totuși, are unele dezavantaje pe care le putem rezolva prin intermediul unui cod suplimentar. Această abordare eșuează pentru următoarea adresă URL validă.

//cdn.google.com/script.js

Putem adăuga protocolul lipsă în prealabil pentru a evita acest lucru. De asemenea, nu reușește să detecteze următoarele url-uri invalide.

http://w
http://..

Deci, de ce să verificăm întreaga adresă URL? Putem verifica doar domeniul. Am împrumutat de aici regex-ul pentru verificarea domeniului.

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;
    }
}

hostname este un șir gol pentru javascript:void(0)deci funcționează și pentru acesta, și puteți adăuga și un verificator de adresă IP. Aș dori să rămân cel mai mult la API-urile native și sper să înceapă să suporte totul în viitorul apropiat.

Comentarii

  • Interesant, dar ar putea fi nevoie să mai lucreze la regex, deoarece acum a introdus false negative care new URL nu are în testele pe care le-am făcut. Acest lucru este de asteptare: http://142.42.1.1 //false și blocarea șirurilor unicode înalte. –  > Por aamarks.
Daniel Faure

Întrebarea solicită o metodă de validare pentru o adresă URL de tipul stackoverflow, fără protocol sau punct în numele de gazdă. Deci, nu este vorba de validarea sintaxei url-ului, ci de verificarea dacă este un url valid, prin apelarea efectivă a acestuia.

Am încercat mai multe metode pentru a ști dacă url-ul adevărat există și este apelabil din browser, dar nu am găsit nicio metodă de a testa cu javascript antetul de răspuns al apelului:

  • adăugarea unui element de ancorare este bună pentru a lansa apelul click() metoda.
  • efectuarea unui apel ajax la url-ul provocator cu 'GET' este în regulă, dar are diverse limitări din cauza CORS politici și nu este cazul utilizării ajaxpentru că url-ul poate fi oricare în afara domeniului serverului meu.
  • folosind metoda fetch API are o soluție de rezolvare similară cu ajax.
  • O altă problemă este că serverul meu se află sub https protocol și aruncă o excepție atunci când apelează urls nesecurizate.

Deci, cea mai bună soluție la care mă pot gândi este obținerea unui instrument care să efectueze CURL folosind javascript, încercând ceva de genul curl -I <url>. Din păcate nu am găsit nici unul și în aparență nu este posibil. Voi aprecia orice comentarii pe această temă.

Dar, în cele din urmă, am un server care rulează PHP și cum folosesc Ajax pentru aproape toate cererile mele, am scris o funcție pe partea de server pentru a efectua cererea curl acolo și a reveni în browser.

În ceea ce privește url-ul cu un singur cuvânt la întrebarea „stackoverflow”, acesta mă va duce la https://daniserver.com.ar/stackoverflow, unde daniserver.com.ar este domeniul meu propriu.

Comentarii

  • Probabil că OP ar fi trebuit să indice mai mult care a fost intenția sa. Problema cu siguranță variază în funcție de nevoile dumneavoastră și dacă este mai important să excludeți falsurile pozitive sau să includeți falsele negative. Așa cum este enunțată problema nu mi se pare că există un răspuns. Se poate lua cu adevărat foo și să presupunem că este http sau https sau .com sau .es sau oricare dintre nenumăratele sufixe? Trebuie să continui să arunci cu tot felul de chestii până când obții un adevărat? –  > Por aamarks.
rosenfeld

Aceasta pare a fi una dintre cele mai dificile probleme din CS 😉

Iată o altă soluție incompletă care funcționează destul de bine pentru mine și mai bine decât celelalte pe care le-am văzut aici. Folosesc un input[type=url] pentru aceasta pentru a suporta IE11, altfel ar fi mult mai simplu să folosesc window.URL pentru a efectua validarea în schimb:

Pentru a accepta intrări incomplete, cum ar fi „www.mydomain.com”, va face, de asemenea, validarea presupunând că protocolul este „http” în aceste cazuri și va returna URL-ul valid dacă adresa este validă. Se returnează false în cazul în care este invalidă.

De asemenea, acceptă domenii IPv4, dar nu și IPv6.

rdans

În cazul meu, singura mea cerință este ca datele introduse de utilizator să nu fie interpretate ca o legătură relativă atunci când sunt plasate în href-ul unei etichete a, iar răspunsurile de aici au fost fie un pic cam OTT pentru asta, fie au permis URL-uri care nu îndeplinesc cerințele mele, așa că asta este ceea ce am ales:

^https?://.+$

Același lucru ar putea fi realizat destul de ușor fără regex.

user8094098

Aceasta nu este cu siguranță cea mai eficientă abordare, dar este ușor de citit și ușor de format pentru orice aveți nevoie. Și este mai ușor să adăugați regex/complexitate de aici. Iată deci o abordare foarte pragmatică

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;
}

TEST:

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);
        });
    });
});

greg.arnott

Există câteva teste care utilizează constructorul URL care nu delimitează dacă intrarea este un șir de caractere sau un obiect 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;  
    }
}

J-a-n-u-s

Actualizare 2020. pentru a extinde ambele răspunsuri excelented de la @iamnewton și @Fernando Chavez Herrera am început să văd @ fiind utilizat în calea URL-urilor.

Deci, regex-ul actualizat este:

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%[email protected]]*)*(\?[;&a-z\d%_.~+=-]*)?(\#[-a-z\d_]*)?$', 'i');

Dacă doriți să o permiteți în șirul de interogare și hash, utilizați:

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%[email protected]]*)*(\?[;&a-z\d%[email protected]]*)?(\#[-a-z\[email protected]]*)?$', 'i');

Acestea fiind spuse, nu sunt sigur dacă există o regulă de hârtie albă care să interzică @ în șirul de interogare sau în hash.

Michael Ecklund

Iată o verificare foarte simplă pentru a vă asigura că există un protocol valid, iar extensia domeniului trebuie să aibă două sau mai multe caractere.

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
    );

};

Mark Hetherington

Dacă aveți nevoie să suportați și https://localhost:3000 atunci folosiți această versiune modificată a regex-ului [Devshed]s.

    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);
    }