it-swarm.com.de

Prüfen Sie, ob eine JavaScript-Zeichenfolge eine URL ist

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

RegExes werden ausgeschlossen, da die URL höchstwahrscheinlich wie stackoverflow geschrieben wird. das heißt, dass es möglicherweise keinen .com, www oder http hat.

153
Bruno

Eine verwandte Frage mit einer Antwort:

Javascript-Regex-URL-Übereinstimmung

Oder diese 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);
}
68
Tom Gullen
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);
}
156
Zemljoradnik

Anstelle eines regulären Ausdrucks würde ich empfehlen, ein Ankerelement zu verwenden. 

wenn Sie die href-Eigenschaft einer anchor festlegen, 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 jedoch der Wert, an den href gebunden ist, keine gültige URL ist, ist der Wert dieser Hilfseigenschaften die leere Zeichenfolge.

Edit: wie in den Kommentaren angegeben: Wenn eine ungültige URL verwendet wird, können die Eigenschaften der aktuellen URL ersetzt werden.

Solange Sie nicht die URL der aktuellen Seite ü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);
}
74
Luke

Sie können versuchen, URL constructor zu verwenden: Wenn es nicht ausgelöst wird, ist der String eine gültige URL:

const isValidUrl = (string) => {
  try {
    new URL(string);
    return true;
  } catch (_) {
    return false;  
  }
}
36
Pavlo

Um URLs mit Javascript zu überprüfen, 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;
  }
}
25
kavitha Reddy

Verbesserung der akzeptierten Antwort ...

  • Überprüfen Sie das Protokoll auf ftp/ftps
  • Hat ein doppeltes Escape für Backslashes (\\)
  • Stellt sicher, dass Domänen einen Punkt und eine Erweiterung haben (.com .io .xyz)
  • Erlaubt vollen Doppelpunkt (:) im Pfad, z. http://thingiverse.com/download:1894343
  • Erlaubt kaufmännisches Und (&) im Pfad z.B. http://en.wikipedia.org/wiki/Procter_&_Gamble
  • Erlaubt das @ -Zeichen im Pfad, z. 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);
    }
    
20
TechyTimo

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.";
}
19
Michael Bushe

Ich verwende die folgende Funktion, um die URL mit oder ohne http/https zu überprüfen:

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

var testCase1 = "http://en.wikipedia.org/wiki/Procter_&_Gamble";
console.log(isValidURL(testCase1)); // return true

var testCase2 = "http://www.google.com/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&docid=nIv5rk2GyP3hXM&tbnid=isiOkMe3nCtexM:&ved=0CAUQjRw&url=http%3A%2F%2Fanimalcrossing.wikia.com%2Fwiki%2FLion&ei=ygZXU_2fGKbMsQTf4YLgAQ&bvm=bv.65177938,d.aWc&psig=AFQjCNEpBfKnal9kU7Zu4n7RnEt2nerN4g&ust=1398298682009707";
console.log(isValidURL(testCase2)); // return true

var testCase3 = "https://sdfasd";
console.log(isValidURL(testCase3)); // return false

var testCase4 = "dfdsfdsfdfdsfsdfs";
console.log(isValidURL(testCase4)); // return false

var testCase5 = "magnet:?xt=urn:btih:123";
console.log(isValidURL(testCase5)); // return false

var testCase6 = "https://stackoverflow.com/";
console.log(isValidURL(testCase6)); // return true

var testCase7 = "https://w";
console.log(isValidURL(testCase7)); // return false

var testCase8 = "https://sdfasdp.ppppppppppp";
console.log(isValidURL(testCase8)); // return false

16
VicJordan

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

10
Ryan

(Ich habe keine Wiederholungen, um das ValidURL -Beispiel zu kommentieren; poste dies daher als Antwort.)

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

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

Wie bereits erwähnt, scheint der reguläre Ausdruck jedoch nicht der beste Ansatz für die Überprüfung von URLs zu sein. 

8
ko la

Ich kann nicht den Beitrag kommentieren, der am nächsten liegt # 5717133 , aber unten habe ich herausgefunden, wie man @ tom-gullen regex zum Laufen bringt.

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

Wie bereits erwähnt, ist der perfekte Regex schwer fassbar, scheint jedoch immer noch ein vernünftiger Ansatz zu sein (Alternativen sind serverseitige Tests oder die neue experimentelle URL-API ). Die hochrangigen Antworten geben häufig für häufig verwendete URLs den Wert "false" aus, aber noch schlimmer wird Ihre App/Seite für Minuten einfrieren, selbst wenn es sich um einen einfachen String wie isURL('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa') handelt. In einigen Kommentaren wurde darauf hingewiesen, aber es wurde wahrscheinlich kein schlechter Wert eingegeben, um es zu sehen. Das Aufhängen macht den Code in jeder ernsthaften Anwendung unbrauchbar. Ich denke, es liegt an den wiederholten Groß- und Kleinschreibung 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, aber es funktioniert natürlich nicht wie gewünscht. Aber auch mit dem Flag ignorieren ignorieren diese Tests die zulässigen hohen Unicode-Werte.

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 Testzeichenfolgen sehen können, die durch sie laufen. Es gibt eine Verzweigung, die zulässt, dass Zeichenfolgen das Protokoll google.com fehlt, obwohl Sie dann wahrscheinlich zu viele Annahmen machen. Das Repository wurde aktualisiert und ich habe nicht vor, hier einen Spiegel aufrecht zu erhalten. Es wurde in separate Tests aufgeteilt, um RegEx redos zu vermeiden, das für DOS-Angriffe ausgenutzt werden kann so lange, dass Ihr Besucher Ihre Website verlässt).

Es gibt ein anderes Repository, das ich gesehen habe, dass für isURL unter dperini/regex-weburl.js sogar besser sein könnte, aber es ist sehr komplex. Es verfügt über eine größere Testliste mit gültigen und ungültigen URLs. Das einfache oben führt immer noch alle Positiven durch und blockiert nur wenige Negative wie http://a.b--c.de/ sowie die speziellen ips.

Was auch immer Sie wählen, führen Sie diese Funktion durch, die ich aus den Tests von dperini/regex-weburl.js angepasst habe, während Sie die Developer Tools Ihres Browsers verwenden.

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.

In diesem Vergleich von isURL regex von Mathias Bynens finden Sie weitere Informationen, bevor Sie einen scheinbar großen Regex posten.

5
aamarks

Eine Funktion, die ich zum Überprüfen einer URL "Zeichenfolge" verwendet 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, ob die Zeichenfolge eine URL ist.

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

das funktioniert bei 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);
}
2
HeshamSalama

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

^https?://.+$

Dasselbe könnte ohne Regex ziemlich leicht erreicht werden.

1
rdans

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 überprüfen, sondern zu prüfen, ob es sich um eine gültige URL handelt, indem sie tatsächlich aufgerufen wird.

Ich habe verschiedene Methoden ausprobiert, um zu wissen, ob die URL wahr ist und vom Browser aus aufgerufen werden kann. Ich habe jedoch keine Möglichkeit gefunden, den Antwortheader des Aufrufs mit Javascript zu testen:

  • wenn Sie ein Ankerelement hinzufügen, können Sie die click()-Methode starten. 
  • ajax den Aufruf der anspruchsvollen URL mit 'GET' durchzuführen, ist in Ordnung, hat jedoch aufgrund von CORS-Richtlinien verschiedene Einschränkungen, und es ist nicht der Fall, dass ajax verwendet wird, da die URL möglicherweise außerhalb der Domäne meines Servers liegt.
  • mit der fetch API hat eine ähnliche Problemumgehung wie ajax.
  • ein anderes Problem ist, dass ich meinen Server unter https protokolliere und beim Aufruf von nicht sicheren URLs eine Ausnahme auslöst.

Also, die beste Lösung, die ich mir vorstellen kann, ist, ein Werkzeug zur Ausführung von CURL mit Javascript zu erhalten, das so etwas wie curl -I <url> versucht. Leider habe ich keine gefunden und in scheinbarer Hinsicht ist dies nicht möglich. Ich freue mich über Kommentare dazu.

Aber am Ende habe ich einen Server, auf dem PHP ausgeführt wird, und da ich Ajax für fast alle meine Anforderungen verwende, schrieb ich auf der Serverseite eine Funktion, um die Curl-Anforderung dort auszuführen und zum Browser zurückzukehren. 

Bezüglich der einzelnen Word-URL zu der Frage 'stackoverflow' wird es zu https://daniserver.com.ar/stackoverflow führen, wobei daniserver.com.ar meine eigene Domäne ist. 

1
Daniel Faure

Sie können die native URL von URL verwenden:

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

Dies ist mit reinem Regex sehr schwierig, da URLs viele Nachteile haben.

  1. Beispielsweise haben Domänennamen komplizierte Einschränkungen für Bindestriche:

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

    b. Das erste Zeichen und das letzte Zeichen des Domainnamens dürfen jedoch kein Bindestrich sein

    c. Das 3. und 4. Zeichen dürfen nicht beide Bindestrich sein 

  2. Ebenso kann die Portnummer nur im Bereich 1-65535 liegen. Dies ist leicht zu überprüfen, wenn Sie den Portteil extrahieren und in int konvertieren, aber es ist ziemlich schwierig, dies mit einem regulären Ausdruck zu überprüfen.

  3. Es gibt auch keine einfache Möglichkeit, gültige Domain-Endungen zu überprüfen. Einige Länder haben Second-Level-Domains (wie 'co.uk'), oder die Erweiterung kann ein langes Wort wie '.international' sein. Und neue TLDs werden regelmäßig hinzugefügt. Diese Art von Dingen kann nur anhand einer hartcodierten Liste geprü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 erledigt, außer:

  • Fall 1. c
  • Akzeptiert eine beliebige 1-5-stellige Portnummer
  • Akzeptiert alle Erweiterungen mit 2-13 Zeichen
  • Akzeptiert kein FTP, Magnet 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] + ']');
}

1
Caner

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

Hier ist eine weitere unvollständige Lösung, die für mich gut genug und besser als die anderen ist, die ich hier gesehen habe. Ich verwende dazu eine Eingabe [type = url], um IE11 zu unterstützen. Andernfalls wäre die Verwendung von window.URL viel einfacher, stattdessen die Überprüfung 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 dies ebenfalls gültig, sofern das Protokoll in diesem Fall "http" ist und die gültige URL zurückgegeben wird, wenn die Adresse gültig ist. Wenn ungültig, wird false zurückgegeben.

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

0
rosenfeld

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 das optionale Objekt options als zweites Argument von isURL übergeben.

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_whitelist und Host_blacklist können 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
0
Ilyich

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

Sie können einfach type="url" in Ihrer Eingabe verwenden und mit checkValidity() 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
    }
});
0

Hier ist nur eine sehr einfache Überprüfung, um sicherzustellen, dass es ein gültiges Protokoll gibt. Die Domain-Endung muss aus zwei oder mehr Zeichen bestehen.

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

};
0
Michael Ecklund

Ich denke, dass die native URL API besser ist 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 auch nicht erkannt.

http://w
http://..

Warum also die gesamte URL überprüfen? Wir können nur die Domain überprüfen. Ich habe mir die Regex entlehnt, um die Domäne von hier 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 hostname-Attribut ist eine leere Zeichenfolge für javascript:void(0), daher funktioniert es auch und Sie können auch eine IP-Adressüberprüfung hinzufügen. Ich würde mich gerne an die meisten nativen APIs halten und hoffe, dass dies in naher Zukunft alles unterstützt. 

0
Munim Munna