web-dev-qa-db-ja.com

JavaScriptの文字列がURLかどうかを確認

JavaScriptで文字列がURLかどうかを確認する方法はありますか?

URLはほとんどの場合stackoverflowのように記述されているため、RegExesは除外されます。つまり、.comwwwhttpがない可能性があるということです。

186
Bruno

回答がある関連質問:

Javascriptの正規表現のURLの一致

またはこの正規表現から 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);
}
89
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);
}
157
Zemljoradnik

正規表現を使用するのではなく、アンカー要素を使用することをお勧めします。

hrefanchorプロパティを設定すると、他のさまざまなプロパティが設定されます。

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"

ソース

ただし、hrefがバインドされている値が有効なURLではない場合、それらの補助プロパティの値は空の文字列になります。

コメントで指摘されているように編集::無効なURLが使用されている場合、現在のURLのプロパティが代用されるかもしれません。

現在のページのURLを渡さない限り、次のようにすることができます。

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

あなたは URL constructor を使うことを試みることができます:それが投げないなら、ストリングは有効なURLです:

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

Javascriptを使ってURLを検証する方法は以下の通りです。

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;
  }
}
27
kavitha Reddy

私はhttp/httpsの有無にかかわらずURLを検証するために下記の関数を使用しています:

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
25
VicJordan

図書館に頼る: https://www.npmjs.com/package/valid-url

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

受け入れられた答えの改善...

  • プロトコルとしてftp/ftpsをチェック
  • バックスラッシュを二重にエスケープする(\\)
  • ドメインにドットと拡張子(.com .io .xyz)が付いていることを確認します。
  • パスにフルコロン(:)を使用できます。 http://thingiverse.com/download:189434
  • パスにアンパサンド(&)を使用できます。例: http://en.wikipedia.org/wiki/Procter_&_Gamble
  • パスに@記号を許可します。 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);
    }
    
21
Mwirabua Tim

これはまた別の方法です。

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

ValidURL exampleにコメントする担当者はいません。したがって、これを回答として投稿してください。)

プロトコル相対URLの使用はお勧めできませんが( プロトコル相対URL )、採用されることがあります。そのようなURLを正規表現で検証するには、プロトコル部分をオプションにすることができます。

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

他の人が指摘したように、正規表現はURLを検証するのにもっとも適したアプローチではないようです。

8
ko la

一番近い投稿にコメントすることはできません #57171 、@ tom-gullenの正規表現を動作させる方法を以下に示します。

/^(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
6
iamnewton

すでに述べたように、完全な正規表現はわかりにくいですが、それでも妥当な方法であるように思われます(代替方法はサーバーサイドテストまたは新しい実験的な方法です RL API )。しかし、ランキングの高い回答は一般的なURLではfalseを返すことがよくありますが、さらに悪いことにisURL('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')のような単純な文字列であっても数分間アプリケーション/ページがフリーズする可能性があります。いくつかのコメントで指摘されていますが、おそらくそれを見るために悪い値を入力していません。そのようにぶら下がっていると、そのコードは深刻なアプリケーションでは使用できなくなります。 ((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|' ...のようにコードで大文字と小文字を区別しないセットが繰り返されているためだと思います。 'i'を取り出すとハングしませんが、もちろん望みどおりには動作しません。しかし、case ignoreフラグがあっても、それらのテストは許可されている高いUnicode値を拒否します。

最もよく言及されているのは:

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

それはGithubから来ています segmentio/is-url 。コードレポジトリの良いところは、テストや問題点、さらにテスト文字列も確認できることです。 google.comのようにプロトコルに欠けている文字列を許可するブランチがあります。 リポジトリは更新されており、ここでミラーを維持するつもりはありません。これは、DOSの攻撃に悪用される可能性があるRegEx redos を避けるために別々のテストに分割されています(クライアントサイドのjsを使って心配する必要はないと思いますが、あなたのことを心配する必要はありません)あなたの訪問者があなたのサイトを離れるほど長い間ページがハングしています。

IsURLにはの方が dperini/regex-weburl.jsの方が良い場合があることを私が見たもう1つのリポジトリがあります。しかしそれは非常に複雑です。有効なURLと無効なURLのより大きなテストリストがあります。上記の単純なものは、まだすべての正の値を渡しますが、http://a.b--c.de/や特別なipsのようないくつかの奇数の負値をブロックすることはできません。

どちらを選んだとしても、あなたのブラウザのDeveloper Tools inpectorを使っている間に、dperini/regex-weburl.jsのテストから適応させたこの関数を通してそれを実行してください。

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

そして、その文字列の 'a'をテストします。

一見素晴らしい正規表現を投稿する前に、詳しくは--- isURL正規表現の比較 Mathias Bynensによるを参照してください。

5
aamarks

URLの "文字列"を検証するために使用してきた1つの機能は次のとおりです。

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

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

この関数は、文字列がURLかどうかにかかわらずブール値を返します。

例:

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

あなたは RLネイティブAPI を使用することができます:

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

これは私と一緒に働いて

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

URLには多くの「不都合」があるため、これは純粋な正規表現では非常に困難です。

  1. たとえば、ドメイン名にはハイフンに対する複雑な制限があります。

    a。途中に多数の連続するハイフンを含めることができます。

    b。ただし、ドメイン名の最初の文字と最後の文字をハイフンにすることはできません

    c。 3番目と4番目の文字を両方ともハイフンにすることはできません

  2. 同様に、ポート番号は1〜65535の範囲内にのみ指定できます。これは、port部分を抽出してintに変換するかどうかを確認するのは簡単ですが、正規表現で確認するのは非常に困難です。

  3. 有効なドメイン拡張子を確認する簡単な方法もありません。国によっては、 セカンドレベルドメイン ( 'co.uk'など)、または拡張子が '.international'などの長いWordになることがあります。そして新しいTLDが定期的に追加されます。この種のことは、ハードコーディングされたリストに対してのみ確認できます。 ( https://en.wikipedia.org/wiki/Top-level_domain を参照)

  4. それからマグネットのURL、FTPアドレスなどがあります。これらはすべて異なる要件があります。

それにもかかわらず、これは以下を除くほとんどすべてを処理する関数です:

  • ケース1。c
  • 1〜5桁の任意のポート番号を受け入れます
  • 任意の拡張子2〜13文字を受け入れます
  • FTP、マグネットなどを受け付けません。
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] + ']');
}
2
Caner

私の場合、私の唯一の要件は、タグのhrefに置かれたときにユーザー入力が相対リンクとして解釈されず、それに対する答えが少しOTTであるか、URLが私の要件を満たさないことを許可することです。私が一緒に行っているものです:

^https?://.+$

同じことが正規表現なしでかなり簡単に達成できます。

1
rdans

質問は、プロトコルやホスト名にドットが含まれていないstackoverflowなどのURLの検証方法を尋ねます。そのため、urlのsintaxを検証するのではなく、実際にそれを呼び出して、それが有効なurlであるかどうかを確認することになります。

私はURLの真が存在し、ブラウザ内から呼び出し可能であるかどうかを知るためにいくつかの方法を試してみましたが、javascriptで呼び出しの応答ヘッダをテストする方法を見つけられませんでした。

  • click()メソッドを起動するには、アンカー要素を追加しても問題ありません。
  • 'GET'を使って挑戦的なURLをajaxで呼び出すのは問題ありませんが、CORSポリシーのためにさまざまな制限があり、ajaxを使用する場合はそうではありません。
  • APIの取得 を使用すると、ajaxに似た回避策があります。
  • 他の問題は私がhttpsプロトコルの下で私のサーバーを持っていて、安全でないURLを呼ぶとき例外を投げることです。

だから、私が考えることができる最善の解決策はcurl -I <url>のようなものを試してjavascriptを使ってCURLを実行するための何らかのツールを手に入れることです。残念ながら私はそれを見つけることができませんでした、そして、美しくそれは不可能です。これについてのコメントに感謝します。

しかし、最終的にはPHPを実行しているサーバーがあり、ほぼすべての要求にAjaxを使用しているので、そこでサーバー側でcurl要求を実行してブラウザに戻る関数を作成しました。

「stackoverflow」という質問に対する単一のWord URLに関しては、daniserver.com.arが私自身のドメインであるhttps://daniserver.com.ar/stackoverflowに私を導くでしょう。

1
Daniel Faure

これはCSで最も困難な問題の1つのようです。

これは私にとって十分にうまく機能し、私がここで見た他のものよりも優れているもう一つの不完全な解決策です。私はIE11をサポートするためにこのためにinput [type = url]を使用しています。そうでなければ検証を実行するためにwindow.URLを使うほうがずっと簡単でしょう:

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

"www.mydomain.com"のような不完全な入力を受け入れるためには、その場合はプロトコルが "http"であると仮定してそれを有効にし、アドレスが有効ならば有効なURLを返します。無効な場合はfalseを返します。

IPv4ドメインもサポートしますが、IPv6はサポートしません。

0
rosenfeld

validator.js を使用します

ES6

import isURL from 'validator/lib/isURL'

isURL(string)

ES6なし

var validator = require('validator');

validator.isURL(string)

オプションのoptionsオブジェクトをisURLの2番目の引数として渡すことにより、この関数の動作を微調整することもできます。

デフォルトの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およびHost_blacklistはホストの配列にすることができます。また、正規表現もサポートしています。

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

入力タイプを変更できる場合、このソリューションははるかに簡単だと思います:

入力でtype="url"を簡単に使用し、jsでcheckValidity()でチェックできます

例えば:

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

有効なプロトコルがあることを確認するための非常に単純なチェックです。ドメイン拡張子は2文字以上にする必要があります。

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

@pavloが示唆しているように、ネイティブの RL API を使用する方が複雑な正規表現パターンよりも優れていると思います。それにはいくつかの欠点がありますが、追加のコードで修正できます。このアプローチは、次の有効なURLでは失敗します。

//cdn.google.com/script.js

これを避けるために、欠けているプロトコルを事前に追加することができます。また、次の無効なURLの検出にも失敗します。

http://w
http://..

では、なぜURL全体をチェックするのでしょうか。ドメインをチェックするだけです。ここ からドメインを検証するために正規表現を借りました。

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属性はjavascript:void(0)の空の文字列なので、そのためにも機能します。また、IPアドレス検証を追加することもできます。私はネイティブAPIのほとんどに固執したいです、そしてそれが近い将来にすべてをサポートし始めることを願っています。

0
Munim Munna