Überprüfen Sie, ob eine JavaScript-Zeichenfolge eine URL ist

283

Gibt es in JavaScript eine Möglichkeit zu überprüfen, ob eine Zeichenfolge eine URL ist?

RegExes werden ausgeschlossen, da die URL höchstwahrscheinlich wie folgt geschrieben ist stackoverflow. das heißt , dass es nicht haben könnte .com, wwwoder http.

Bruno
quelle
22
Wenn das fehlt http, ist es standardmäßig keine URL.
Nfechner
1
@nfechner das heißt, wenn es kein Protokoll angibt und das Doppelpunktzeichen verwendet (vorzugsweise mit zwei Schrägstrichen als nächstes), dann ist es keine URL?
Jcolebrand
5
Wie Sie im URL-RFC lesen können, ist der Doppelpunkt der einzige Teil, der tatsächlich erforderlich ist, um einen String zu einer gültigen URL zu machen. Gültige URLs sehen aus wie:<scheme>:<scheme-specific-part>
nfechner
8
Wie Sie testen, ob es sich bei einer URL um eine URL handelt, ist stark kontextabhängig und ohne weitere Qualifizierung zu vage. Ist es für Sie wichtig, ob es der URL-RFC-Spezifikation entspricht, beim Aufrufen der URL durch ein Betriebssystem funktioniert , als hrefin einem Ankerelement analysiert wird , beim Aufrufen funktioniert window.open(url), auf etwas verweist, das wirklich vorhanden ist, am Browser funktioniert Bar oder eine Kombination der oben genannten? Sie erhalten sehr unterschiedliche Antworten, je nachdem, welche davon Ihnen wichtig sind.
Roy Tinker

Antworten:

189

Eine verwandte Frage mit einer Antwort:

Übereinstimmende Javascript-Regex-URL

Oder dieser Regexp von 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);
}
Tom Gullen
quelle
1
Ich weiß, aber ich suche in meinen Lesezeichen und die meisten von ihnen sind wie Stackoverflow (ohne .com usw.) geschrieben
Bruno
3
@Bruno: Es ist sehr wahrscheinlich, dass sie intern mit separaten Titeln und URLs gespeichert werden, wie z. B. { title: "Stackoverflow", uri: "http://stackoverflow.com" } Update: siehe code.google.com/chrome/extensions/bookmarks.html
Marcel Korpel
10
versuchen, Ihr Beispiel zu verwenden. Aber ich bekomme einen Fehler auf Firebug, der sagt invalid quantifier. Irgendeine Idee?
Sisir
125
Funktionsrückgabe: 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 (Version 30.0.1599.101) (Mac OS X: 10.8.5)
dr.dimitru
10
Beachten Sie, dass Sie RegExpdie Backslashes doppelt maskieren müssen , wenn Sie eine Zeichenfolge als Parameter für das verwenden. Andernfalls werden Fehler wie eine ungültige Gruppe angezeigt .
Kjell
165
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);
}
Zemljoradnik
quelle
13
schlägt für Google-Suche Bild-Links fehl: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
Rechnung Davis
7
das ist unbrauchbar langsam
Hernán Eche
3
@ HernánEche Was meinst du mit langsam ? start = new Date(); isURL("http://michalstefanow.com"); end = new Date(); diff = end - start; console.log(diff)Ich stellte einen Wasserkocher auf, ging auf eine Toilette, rief meine Mutter an und die Sache war in kürzester Zeit erledigt ...
Mars Robertson
62
Es kehrt zurück truefür aaa.
Alex Naumov
1
Dies sollte absolut nicht die richtige Antwort sein. Es schlägt viele Testfälle fehl und, was noch wichtiger ist, es hängt Ihre Seite sogar an einer kurzen Zeichenfolge: isURL('12345678901234567890123')Fügen Sie weitere Zeichen hinzu und es ist noch schlimmer.
aamarks
141

Sie können versuchen, den URLKonstruktor zu verwenden : Wenn er nicht ausgelöst wird, ist die Zeichenfolge eine gültige URL:

function isValidUrl(string) {
  try {
    new URL(string);
  } catch (_) {
    return false;  
  }

  return true;
}

Der Begriff 'URL' ist in RFC 3886 (als URI) definiert. Es muss mit einem Schemanamen beginnen, und der Schemaname ist nicht auf http / https beschränkt.

Bemerkenswerte Beispiele:

  • www.google.com ist keine gültige URL (fehlendes Schema)
  • javascript:void(0) ist eine gültige URL, jedoch keine HTTP-URL
  • http://..ist eine gültige URL, wobei der Host ist ..; Ob es aufgelöst wird, hängt von Ihrem DNS ab
  • https://google..com ist eine gültige URL wie oben

Wenn Sie überprüfen möchten, ob eine Zeichenfolge eine gültige HTTP-URL ist:

function isValidHttpUrl(string) {
  let url;

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

  return url.protocol === "http:" || url.protocol === "https:";
}
Pavlo
quelle
13
@AshD nein, ist es nicht; zB können Sie nicht als hrefAttribut für verwenden <a>. Eine gültige URL muss mit einem Schemanamen beginnen , z https://.
Pavlo
3
neue URL ('Javascript: alert (23)')
Blade091
6
@Pavlo dies gibt wahr zurückisValidUrl("javascript:void(0)")
Praveena
3
Ich mag das, um mir neue Dinge über js beizubringen! Es hat keine falschen Negative, die ich finden könnte. Es hat einige Fehlalarme: http://..Oderhttp:///a
aamarks
2
Die URL funktioniert ab Edge, sodass möglicherweise nicht alles darunter funktioniert, wie Sie es erwarten. Stellen Sie sicher, dass Sie zuerst die Kompatibilität überprüfen.
Tony T.
97

Anstatt einen regulären Ausdruck zu verwenden, würde ich empfehlen, ein Ankerelement zu verwenden.

Wenn Sie die hrefEigenschaft von festlegen anchor, werden verschiedene andere Eigenschaften festgelegt.

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"

Quelle

Wenn der hrefgebundene Wert jedoch keine gültige URL ist, ist der Wert dieser Hilfseigenschaften die leere Zeichenfolge.

Bearbeiten: Wie in den Kommentaren ausgeführt: Wenn eine ungültige URL verwendet wird, können die Eigenschaften der aktuellen URL ersetzt werden.

Solange Sie die URL der aktuellen Seite nicht übergeben, können Sie Folgendes tun:

function isValidURL(str) {
   var a  = document.createElement('a');
   a.href = str;
   return (a.host && a.host != window.location.host);
}
Luke
quelle
3
Dies ist nicht der Fall (zumindest in Chrome 48). Wenn die übergebene URL a.hrefungültig ist, wird parser.hostder Hostname der Seite zurückgegeben, auf der Sie sich gerade befinden, nicht der erwartete false.
Sam Beckham
2
Gah! das ist komisch Ich schwöre, ich habe das getestet! Ich denke, es ist fair zu sagen, dass dies auf der aktuellen Seite nicht wirklich verwendet werden muss, so dass die Bedingung einfach geändert werden kann. Ich werde den Beitrag bearbeiten.
Luke
Es ist kein sehr typischer Anwendungsfall, aber diese Technik funktioniert nicht im Kontext des Firefox-Browserfensters (wichtig für die Addon-Entwicklung)
chrmod
@SamBeckham Dies ist definitiv ein Problem bei der Verwendung dieser Methode, aber ich möchte nur darauf hinweisen, dass dies kein besonderes Verhalten ist. Wenn Sie einen Link auf Ihrer Seite haben , die ungültig ist, wie <a href="invalidurl">es sich auf Ihre Domain gehen. Es wird am Ende der aktuellen URL hinzugefügt. Chrome macht also das Richtige, indem es Ihnen den aktuellen Hostnamen aus dem "Parser" -Element gibt.
Yts
4
function isValidURL(str): so viel besser als Regex! Danke dir!
Rodrigo
46

Ich verwende die folgende Funktion, um die URL mit oder ohne zu validieren 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

Vikasdeep Singh
quelle
2
Scheint eine schöne Lösung! Könnten Sie einige Tests hinzufügen, die zeigen, dass es in einigen Eckfällen funktioniert (siehe zum Beispiel diese Kommentare )?
Basj
@Basj Testfälle hinzugefügt. Bitte überprüfen Sie
Vikasdeep Singh
Nicht schlecht, kann http: //⌘.ws oder 142.42.1.1 nicht bestehen und erlaubt http: //.www.foo.bar./, aber es hängt nicht wie einige der anderen regulären Ausdrücke, einschließlich der am besten bewerteten Antworten.
aamarks
@aamarks Ich habe deine Antwort überprüft. Ihre Antwort schlägt fehl, https://sdfasdp.pppppppppppdh Sie kehren zurück, trueaber meine kehrt zurück, falsewas meiner Meinung nach erwartet wird.
Vikasdeep Singh
4
seine Rückkehr ist wahr für [email protected]... sollte es? Ich denke, es sollte nicht
Zohab Ali
35

Das Überprüfen von URL mit Javascript wird unten gezeigt

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;
  }
}
Kavitha Reddy
quelle
3
Einige Teile des regulären Ausdrucks könnten erheblich reduziert werden: a) (http|https)auf (?:https?); b) :{0,1}zu :?; c) [0-9]bis\d
Dmitry Parzhitsky
28

Verlassen Sie sich auf eine Bibliothek: https://www.npmjs.com/package/valid-url

import { isWebUri } from 'valid-url';
// ...
if (!isWebUri(url)) {
    return "Not a valid url.";
}
Michael Bushe
quelle
Dieser gibt mir große Probleme mit seltsamen URLs, die tatsächlich vom Browser analysiert werden, z. B.: {
Ich habe
23

Verbesserung der akzeptierten Antwort ...

  • Suchen Sie nach FTP / Ftps als Protokoll
  • Hat doppelte Flucht für Backslashes (\\)
  • Stellt sicher, dass Domänen einen Punkt und eine Erweiterung haben (.com .io .xyz)
  • Ermöglicht den vollständigen Doppelpunkt (:) im Pfad, z http://thingiverse.com/download:1894343
  • Ermöglicht kaufmännisches Und (&) im Pfad, z. B. http://en.wikipedia.org/wiki/Procter_&_Gamble
  • Ermöglicht das @ -Symbol im Pfad, z. B. 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);
    }
Mwirabua Tim
quelle
5
Nein, es sollte nicht die akzeptierte Antwort sein. Wie einige der anderen hängt es an einer Zeichenfolge von nur 33 Zeichen: isURL ('123456789012345678901234567890123') und besteht viele Edge-Case-Tests nicht: foo.com/blah_blah_(wikipedia)_(again) // gibt fälschlicherweise false zurück.
aamarks
2
Dies liegt daran, dass localhost: 8080 keine gültige URL ist.
Shane
Sollte ftps sein: // localhost: 8080 =)
vp_arth
Es scheint nicht zu funktionieren: hängt an langen Eingaben (wie @aanmarks sagte)
Cecemel
13

Hier ist noch eine andere Methode.

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

Ryan Breece
quelle
Bildungscode! Der Mechanismus hier ist wahrscheinlich identisch mit der Funktionsweise new URL(string)von Pavlos Code. Beide Tests haben identische Ergebnisse mit allen von mir getesteten Randfällen. Ich mag seinen Code, weil er einfacher ist und keine Elemente erstellt, aber Ihr Code ist ein paar Mal schneller (wahrscheinlich, weil er das el nach der ersten Verwendung nicht erstellt).
aamarks
1
Danke dir! Ich habe Ihren Rat umgesetzt. Beachten Sie jedoch Folgendes: Ältere Browser und / oder mobile Geräte WebView hat das Element <input type = url> möglicherweise nicht implementiert. Somit würde der Eingabewert wie ein normaler Text behandelt (keine URL-Validierung). REF: developer.mozilla.org/en-US/docs/Web/HTML/Element/input/url
Panini Luncher
10

(Ich habe keine Mitarbeiter, die das ValidURL- Beispiel kommentieren könnten. Schreiben Sie dies daher als Antwort.)

Die Verwendung protokollbezogener URLs wird zwar nicht empfohlen ( protokollbezogene URL ), sie werden jedoch manchmal verwendet. Um eine solche URL mit einem regulären Ausdruck zu validieren, kann der Protokollteil optional sein, z.

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

Wie andere angemerkt haben, scheint der reguläre Ausdruck jedoch nicht der am besten geeignete Ansatz für die Validierung von URLs zu sein.

ko la
quelle
Ich dachte zuerst, das sei ziemlich gut, aber es scheitert an vielen Tests bei mathiasbynens.be/demo/url-regex , und dann hängt es anisValidURL("https://[email protected]/13176")
aamarks
Ja, wie gesagt, ich habe lediglich den Protokollteil kommentiert. Ich habe die zu behandelnde Authentifizierungsklausel hinzugefügt @. Es hängt nicht in meinen Browsern .
Ko La
Entschuldigung, ich habe einige davon durchgesehen, um sie zu bewerten, und habe übersehen, dass Ihre die gegebene Antwort kommentiert hat. Ich denke, Ihre Korrektur hat mir sogar geholfen, mit diesen zu beginnen, als ich diese Seite zum ersten Mal besuchte. Jetzt nicht hängen.
aamarks
9

Sie können die native URL-API verwenden :

  const isUrl = string => {
      try { return Boolean(new URL(string)); }
      catch(e){ return false; }
  }
Aral Roca
quelle
3
Sieht der Antwort von @pavlo sehr ähnlich, nur Variablennamen geändert;)
Munim Munna
2
Es sollte jetzt wirklich eine einfache native Methode geben, um dies zu überprüfen - diese Antwort sah sehr vielversprechend aus, aber sie kehrt früh zurück, wie oben erwähnt.
zero_cool
8

Wie bereits erwähnt, ist der perfekte reguläre Ausdruck schwer fassbar, scheint aber dennoch ein vernünftiger Ansatz zu sein (Alternativen sind serverseitige Tests oder die neue experimentelle URL-API ). Die hochrangigen Antworten geben jedoch häufig häufig verwendete URLs für häufig verwendete URLs zurück. Schlimmer noch, Ihre App / Seite wird für Minuten eingefroren, selbst wenn es sich um eine so einfache Zeichenfolge wie handelt isURL('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'). In einigen Kommentaren wurde darauf hingewiesen, aber höchstwahrscheinlich wurde kein schlechter Wert eingegeben, um ihn anzuzeigen. Wenn Sie so hängen, wird dieser Code in jeder ernsthaften Anwendung unbrauchbar. Ich denke, es liegt an der wiederholten Groß- und Kleinschreibung ohne Berücksichtigung von Codes im Code wie ((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|' .... Nehmen Sie das 'i' heraus und es hängt nicht, funktioniert aber natürlich nicht wie gewünscht. Aber selbst mit dem Flag "Fall ignorieren" lehnen diese Tests hohe Unicode-Werte ab, die zulässig sind.

Das Beste, was bereits erwähnt wurde, ist:

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

Das kommt von Github segmentio / is-url . Das Gute an einem Code-Repository ist, dass Sie die Tests und alle Probleme sowie die durchlaufenden Testzeichenfolgen sehen können. Es gibt einen Zweig, in dem Zeichenfolgen ohne Protokoll fehlen google.com, obwohl Sie dann wahrscheinlich zu viele Annahmen treffen. Das Repository wurde aktualisiert und ich habe nicht vor, hier einen Spiegel aufrechtzuerhalten. Es wurde in separate Tests unterteilt, um RegEx- Redos zu vermeiden , die für DOS-Angriffe ausgenutzt werden können (ich glaube nicht, dass Sie sich bei clientseitigen js darum kümmern müssen, aber Sie müssen sich Sorgen machen, dass Ihre Seite so lange hängt, bis Ihre Besucher verlässt Ihre Website).

Es gibt ein anderes Repository, das ich gesehen habe und das für isURL unter dperini / regex-weburl.js vielleicht sogar besser ist , aber es ist sehr komplex. Es hat eine größere Testliste mit gültigen und ungültigen URLs. Das einfache oben übergibt immer noch alle positiven und blockiert nur ein paar ungerade Negative wie http://a.b--c.de/sowie die speziellen ips nicht.

Führen Sie diese Funktion aus, die ich aus den Tests auf dperini / regex-weburl.js angepasst habe, und verwenden Sie dabei den Developer Tools Inpector Ihres Browsers.

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

Und dann testen Sie diese Zeichenfolge von 'a'.

Weitere Informationen finden Sie in diesem Vergleich von isURL-Regex von Mathias Bynens, bevor Sie einen scheinbar großartigen Regex veröffentlichen.

aamarks
quelle
Ich habe deine Antwort überprüft. Ihre Antwort schlägt für sdfasdp.ppppppppppp fehl, dh die Rückgabe von wahr, aber erwartet ist falsch
Vikasdeep Singh
1
Ich denke, das ist strukturell eine gültige URL. Kein Experte für den Standard, aber ich glaube nicht, dass die Länge des .com-Teils begrenzt ist (ich weiß, dass .online legitim ist).
aamarks
1
Ich wusste vor ein paar Monaten kaum, wie man einen regulären Ausdruck schreibt. Das Problem ist schwerwiegend. Beide von mir zitierten isURL('a'.repeat(100))regulären Ausdrücke können millionenfach pro Sekunde ausgeführt werden (der komplexere von dperini ist tatsächlich schneller). Einige der hochrangigen Antworten des Formulars ([a-zA-Z] +) * würden Stunden brauchen, um dies einmal auszufüllen. Weitere Informationen finden Sie unter RegEx-Redos.
aamarks
6

Ich kann den Beitrag mit der nächstgelegenen Nummer 5717133 nicht kommentieren , aber unten ist die Art und Weise, wie ich herausgefunden habe, wie @ tom-gullen regex funktioniert.

/^(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
iamnewton
quelle
2
Das hat bei mir funktioniert, aber ich musste die Backslashes rückgängig machen. 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');
Fernando Chavez Herrera
Weitere Testfälle finden Sie unter w3resource.com/javascript-exercises/…
Kewal Shah,
5

Verwenden Sie validator.js

ES6

import isURL from 'validator/lib/isURL'

isURL(string)

Nein ES6

var validator = require('validator');

validator.isURL(string)

Sie können das Verhalten dieser Funktion auch optimieren, indem Sie ein optionales optionsObjekt als zweites Argument von übergebenisURL

Hier ist das Standardobjekt options:

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_whitelistund host_blacklistkann Arrays von Hosts sein. Sie unterstützen auch reguläre Ausdrücke.

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
Iljitsch
quelle
1
Nett! Kleine Bibliothek (weniger als 40.000 minimiert), beliebte Bibliothek (über 3 Millionen wöchentliche Downloads auf npm) bietet Ihnen eine Menge Flexibilität bei der Angabe der Gültigkeit der URLs für Ihren speziellen Anwendungsfall und verfügt neben der URL über eine Reihe weiterer Validatoren. Dies ist bei weitem die beste Antwort, IMHO.
Javid Jamae
4

Eine Funktion, mit der ich eine URL "Zeichenfolge" überprüft habe, ist:

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

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

Diese Funktion gibt einen Booleschen Wert zurück, unabhängig davon, ob es sich bei der Zeichenfolge um eine URL handelt.

Beispiele:

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
Chris
quelle
4

Dies ist mit reinem regulären Ausdruck ziemlich schwierig, da URLs viele "Unannehmlichkeiten" aufweisen.

  1. Zum Beispiel haben Domain-Namen komplizierte Einschränkungen für Bindestriche:

    ein. Es ist erlaubt, viele aufeinanderfolgende Bindestriche in der Mitte zu haben.

    b. Das erste und letzte Zeichen des Domainnamens darf jedoch kein Bindestrich sein

    c. Das 3. und 4. Zeichen können nicht beide Bindestriche sein

  2. Ebenso kann die Portnummer nur im Bereich von 1-65535 liegen. Dies ist leicht zu überprüfen, ob Sie den Port-Teil extrahieren und in konvertieren, intaber mit einem regulären Ausdruck nur schwer zu überprüfen.

  3. Es gibt auch keine einfache Möglichkeit, gültige Domain-Endungen zu überprüfen. Einige Länder haben Domänen der zweiten Ebene (z. B. "co.uk"), oder die Erweiterung kann ein langes Wort wie ".international" sein. Und regelmäßig werden neue TLDs hinzugefügt. Diese Art von Dingen kann nur anhand einer fest codierten Liste überprüft werden. (siehe https://en.wikipedia.org/wiki/Top-level_domain )

  4. Dann gibt es Magnet-URLs, FTP-Adressen usw. Diese haben alle unterschiedliche Anforderungen.

Trotzdem ist hier eine Funktion, die so ziemlich alles handhabt, außer:

  • Fall 1. c
  • Akzeptiert eine beliebige 1-5-stellige Portnummer
  • Akzeptiert alle Zeichen der Erweiterung 2-13
  • Akzeptiert keine FTP, Magnete usw.

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] + ']');
}

Caner
quelle
1

Ich denke, die Verwendung der nativen URL-API ist besser als ein komplexes Regex-Muster, wie @pavlo vorgeschlagen hat. Es hat jedoch einige Nachteile, die wir durch zusätzlichen Code beheben können. Dieser Ansatz schlägt für die folgende gültige URL fehl.

//cdn.google.com/script.js

Wir können das fehlende Protokoll vorher hinzufügen, um dies zu vermeiden. Die folgende ungültige URL wird ebenfalls nicht erkannt.

http://w
http://..

Warum also die ganze URL überprüfen? Wir können nur die Domain überprüfen. Ich habe den regulären Ausdruck ausgeliehen, um die Domain von hier aus zu überprüfen .

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

Das hostnameAttribut ist eine leere Zeichenfolge für javascript:void(0), daher funktioniert es auch dafür, und Sie können auch eine IP-Adressüberprüfung hinzufügen. Ich möchte mich am liebsten an die native API halten und hoffe, dass sie in naher Zukunft alles unterstützt.

Munim Munna
quelle
Interessant, muss aber möglicherweise noch an der Regex arbeiten, da sie jetzt falsche Negative einführt, new URLdie in den von mir durchgeführten Tests nicht vorhanden sind. Dies ruft auf: http://142.42.1.1 //falseund blockiert hohe Unicode-Zeichenfolgen.
aamarks
1

Die Frage fragt nach einer Validierungsmethode für eine URL wie stackoverflow ohne das Protokoll oder einen Punkt im Hostnamen. Es geht also nicht darum, die URL-Sintax zu validieren, sondern zu überprüfen, ob es sich um eine gültige URL handelt, indem Sie sie tatsächlich aufrufen.

Ich habe verschiedene Methoden ausprobiert, um festzustellen, ob die URL true vorhanden ist und über den Browser aufgerufen werden kann, habe jedoch keine Möglichkeit gefunden, den Antwortheader des Aufrufs mit Javascript zu testen:

  • Das Hinzufügen eines Ankerelements ist für das Auslösen der click()Methode in Ordnung .
  • Das Aufrufen der herausfordernden URL mit Ajax 'GET'ist in Ordnung, hat jedoch aufgrund von CORSRichtlinien verschiedene Einschränkungen und wird nicht verwendet ajax, da die URL möglicherweise außerhalb der Domäne meines Servers liegt.
  • Die Verwendung der Abruf-API hat eine ähnliche Problemumgehung wie Ajax.
  • Ein anderes Problem ist, dass ich meinen Server unter httpsProtokoll habe und beim Aufrufen nicht sicherer URLs eine Ausnahme auslöst.

Die beste Lösung, die ich mir CURLvorstellen kann, ist es, ein Tool mit Javascript zu erstellen, das so etwas versucht curl -I <url>. Leider habe ich keine gefunden und anscheinend ist dies nicht möglich. Ich freue mich über Kommentare dazu.

PHPAm Ende läuft jedoch ein Server, und da ich Ajax für fast alle meine Anforderungen verwende, habe ich auf der Serverseite eine Funktion geschrieben, um die Curl-Anforderung dort auszuführen und zum Browser zurückzukehren.

In Bezug auf die URL mit einem einzelnen Wort in der Frage "Stackoverflow" werde ich dahin führen https://daniserver.com.ar/stackoverflow, wo daniserver.com.ar meine eigene Domain ist.

Daniel Faure
quelle
Das OP hätte wahrscheinlich mehr von seiner Absicht angeben sollen. Das Problem hängt sicherlich von Ihren Bedürfnissen ab und davon, ob es wichtiger ist, falsch positive oder falsch negative Ergebnisse auszuschließen. Da das Problem festgestellt wird, scheint es keine Antwort auf mich zu geben. Können Sie wirklich fooannehmen, dass es sich um http oder https oder .com oder .es oder eines der unzähligen Suffixe handelt? Wirfst du das Spülbecken weiter darauf, bis du ein wahres bekommst?
aamarks
1

Dies scheint eines der schwierigsten Probleme in CS zu sein;)

Hier ist eine weitere unvollständige Lösung, die für mich gut genug und besser funktioniert als die anderen, die ich hier gesehen habe. Ich verwende hierfür eine Eingabe [type = url], um IE11 zu unterstützen, andernfalls wäre es viel einfacher, stattdessen window.URL zu verwenden, um die Validierung durchzuführen:

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

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

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

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

Um unvollständige Eingaben wie "www.mydomain.com" zu akzeptieren, wird es auch gültig, vorausgesetzt, das Protokoll ist in diesen Fällen "http" und die gültige URL wird zurückgegeben, wenn die Adresse gültig ist. Es gibt false zurück, wenn es ungültig ist.

Es unterstützt auch IPv4-Domänen, jedoch nicht IPv6.

Rosenfeld
quelle
1

In meinem Fall besteht meine einzige Anforderung darin, dass die Benutzereingabe nicht als relativer Link interpretiert wird, wenn sie in die href eines Tags eingefügt wird, und die Antworten hier waren entweder ein bisschen OTT dafür oder erlaubten URLs, die meinen Anforderungen nicht entsprechen ist was ich gehe mit:

^https?://.+$

Das gleiche könnte ziemlich einfach ohne Regex erreicht werden.

rdans
quelle
1

das arbeitet mit mir

function isURL(str) {
  var regex = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/;
  var pattern = new RegExp(regex); 
return pattern.test(str);
}
HeshamSalama
quelle
1
Diese Antwort wurde bereits vor 4 Jahren von Kavitha Reddy gegeben.
aamarks
Ich habe es einfach und abstrakt gemacht
HeshamSalama
1

Wenn Sie den Eingabetyp ändern können, wäre diese Lösung meiner Meinung nach viel einfacher:

Sie können type="url"Ihre Eingabe einfach verwenden und mit überprüfencheckValidity() in js überprüfen

Z.B:

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
    }
});
Daniel Rodríguez
quelle
1

Dies ist trotzig nicht der effektivste Ansatz, aber es ist lesbar und einfach zu formen, was immer Sie brauchen. Und von hier aus ist es einfacher, Regex / Komplexität hinzuzufügen. Hier ist also ein sehr pragmatischer Ansatz

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

PRÜFUNG:

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

quelle
1

Mathias Bynens hat eine Liste bekannter URL-Regexe zusammengestellt mit Test-URLs zusammengestellt. Es gibt wenig Grund, einen neuen regulären Ausdruck zu schreiben. Wählen Sie einfach eine vorhandene aus, die am besten zu Ihnen passt.

Die Vergleichstabelle für diese regulären Ausdrücke zeigt jedoch auch, dass es nahezu unmöglich ist, eine URL-Validierung mit einem einzelnen regulären Ausdruck durchzuführen. Alle regulären Ausdrücke in Bynens 'Liste erzeugen falsch positive und falsch negative Ergebnisse.

Ich schlage vor, dass Sie einen vorhandenen URL-Parser (z. B. new URL('http://www.example.com/')in JavaScript) verwenden und dann die Überprüfungen, die Sie durchführen möchten, auf die analysierte und normalisierte Form der URL bzw. anwenden. seine Komponenten. Die Verwendung der JavaScript- URLOberfläche hat den zusätzlichen Vorteil, dass nur solche URLs akzeptiert werden, die vom Browser wirklich akzeptiert werden.

Beachten Sie auch, dass möglicherweise technisch inkorrekte URLs weiterhin funktionieren. Zum Beispiel http://w_w_w.example.com/, http://www..example.com/, http://123.example.com/haben alle einen ungültigen Hostnamen Teil aber jeder Browser weiß ich wird versuchen , sie ohne Beschwerden zu öffnen, und wenn Sie die IP - Adressen für die ungültigen Namen angeben , in/etc/hosts/ solche URLs werden auch funktionieren , aber nur auf dem Computer.

Die Frage ist daher nicht so sehr, ob eine URL gültig ist, sondern welche URLs funktionieren und in einem bestimmten Kontext zugelassen werden sollten.

Wenn Sie eine URL-Validierung durchführen möchten, gibt es viele Details und Randfälle, die leicht übersehen werden können:

  • URLs können Anmeldeinformationen wie in enthalten http://user:[email protected]/ .
  • Die Portnummern müssen im Bereich von 0 bis 65535 liegen. Möglicherweise möchten Sie jedoch den Platzhalterport 0 ausschließen.
  • Portnummern können führende Nullen haben, wie in http://www.example.com:000080/ .
  • IPv4-Adressen sind keinesfalls auf 4 Dezimalzahlen im Bereich von 0 bis 255 beschränkt. Sie können ein bis vier Ganzzahlen verwenden, die dezimal, oktal oder hexadezimal sein können. Die URLs https: //010.010.000010.010/ , https: //0x8.0x8.0x0008.0x8/ , https: //8.8.2056/ , https: //8.526344/ , https: // 134744072 / sind alle gültig und nur kreative Schreibweisen https://8.8.8.8/ .
  • Das Zulassen von Loopback-Adressen ( http://127.0.0.1/ ), privaten IP-Adressen ( http://192.168.1.1 ), verbindungslokalen Adressen ( http://169.254.100.200 ) usw. kann sich auf die Sicherheit auswirken oder Privatsphäre. Wenn Sie sie beispielsweise als Adresse von Benutzeravataren in einem Forum zulassen, veranlassen Sie die Browser der Benutzer, unerwünschte Netzwerkanforderungen in ihrem lokalen Netzwerk und im Internet von Dingen zu senden, zu denen solche Anfragen möglicherweise lustige und weniger lustige Dinge verursachen passieren in Ihrem Haus.
  • Aus den gleichen Gründen möchten Sie möglicherweise Links zu nicht vollständig qualifizierten Hostnamen verwerfen, dh Hostnamen ohne Punkt.
  • Hostnamen können jedoch immer einen nachgestellten Punkt haben (wie in http://www.stackoverflow.com.).
  • Der Hostname-Teil eines Links kann spitze Klammern für IPv6-Adressen enthalten, wie in http: // [:: 1] .
  • IPv6-Adressen haben auch Bereiche für private Netzwerke oder verbindungslokale Adressen usw.
  • Wenn Sie bestimmte IPv4-Adressen blockieren, beachten Sie, dass beispielsweise https://127.0.0.1 und https: // [:: ffff: 127.0.0.1] auf dieselbe Ressource verweisen (wenn das Loopback-Gerät Ihres Computers IPv6-fähig ist ).
  • Der Hostname-Teil von URLs kann jetzt Unicode enthalten, sodass der Zeichenbereich [-0-9a-zA-z]definitiv nicht mehr ausreicht.
  • Viele Registrierungen für Top-Level-Domains definieren bestimmte Einschränkungen, z. B. für den zulässigen Satz von Unicode-Zeichen. Oder sie unterteilen ihren Namespace (wie co.ukund viele andere).
  • Domänen der obersten Ebene dürfen keine Dezimalstellen enthalten, und der Bindestrich ist nur für das IDN-A-Label-Präfix "xn--" zulässig.
  • Unicode-Top-Level-Domains (und ihre Punycode-Codierung mit "xn--") dürfen immer noch nur Buchstaben enthalten, aber wer möchte das in einem regulären Ausdruck überprüfen?

Welche dieser Einschränkungen und Regeln gelten, hängt von den Projektanforderungen und dem Geschmack ab.

Ich habe kürzlich einen URL-Validator für eine Web-App geschrieben, der für vom Benutzer bereitgestellte URLs in Foren, sozialen Netzwerken oder dergleichen geeignet ist. Fühlen Sie sich frei, es als Basis für Ihre eigene zu verwenden:

Ich habe auch einen Blog-Beitrag The Gory Details of URL Validation mit detaillierteren Informationen geschrieben.

Guido Flohr
quelle
1

Ich ändere die Funktion in Match + und nehme hier eine Änderung mit den Schrägstrichen und ihrer Arbeit vor: (http: // und https) beide

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;
}
Ashish Gupta
quelle
0

Hier ist nur eine sehr einfache Überprüfung, um sicherzustellen, dass ein gültiges Protokoll vorhanden ist und die Domänenerweiterung aus zwei oder mehr Zeichen bestehen muss.

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

};
Michael Ecklund
quelle
0

Wenn Sie auch Unterstützung benötigen, https://localhost:3000verwenden Sie diese modifizierte Version des regulären Ausdrucks von [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);
    }
Mark Hetherington
quelle
0

Es gibt einige Tests mit dem URL-Konstruktor, bei denen nicht festgelegt wird, ob es sich bei der Eingabe um eine Zeichenfolge oder ein URL-Objekt handelt.

// 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;  
    }
}
greg.arnott
quelle
0

2020 Update. Um sowohl die exzellenten Antworten von @iamnewton als auch von @Fernando Chavez Herrera zu erweitern, habe ich begonnen, zu sehen @, wie sie im Pfad von URLs verwendet werden.

Der aktualisierte reguläre Ausdruck lautet also:

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

Wenn Sie es in der Abfragezeichenfolge und im Hash zulassen möchten, verwenden Sie:

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

Davon abgesehen bin ich mir nicht sicher, ob die Abfragezeichenfolge @oder der Hash eine Whitepaper-Regel nicht zulässt.

Janus
quelle
0

Es gibt bereits viele Antworten, aber hier ist ein weiterer Beitrag: URLVerwenden Sie direkt aus der Polyfill-Gültigkeitsprüfung ein inputElement mit type="url", um die integrierte Gültigkeitsprüfung des Browsers zu nutzen:

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

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

Quelle

Bruno Finger
quelle