web-dev-qa-db-ja.com

JavaScriptを使用してURLを検証しようとしています

URLを検証してメッセージを表示したい。以下は私のコードです:

$("#pageUrl").keydown(function(){
        $(".status").show();
        var url = $("#pageUrl").val();

        if(isValidURL(url)){

        $.ajax({
            type: "POST",
            url: "demo.php",
            data: "pageUrl="+ url,
            success: function(msg){
                if(msg == 1 ){
                    $(".status").html('<img src="images/success.gif"/><span><strong>SiteID:</strong>12345678901234456</span>');
                }else{
                    $(".status").html('<img src="images/failure.gif"/>');
                }
            }
            });

            }else{

                    $(".status").html('<img src="images/failure.gif"/>');
            }

    });


function isValidURL(url){
    var RegExp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;

    if(RegExp.test(url)){
        return true;
    }else{
        return false;
    }
} 

私の問題は、正規表現に一致するまで適切なURLを入力してもエラーメッセージが表示され、URLが"http://wwww"のようなものであってもtrueを返すようになったことです。

あなたの提案に感謝します。

83
vinay

誰かがJquery Validationプラグインに言及しましたが、URLを検証したいだけではやり過ぎだと思われます。プラグインからの正規表現の行は次のとおりです。

return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);

ここから彼らはそれを手に入れました: http://projects.scottsplayground.com/iri/

@nhahtdhからの指摘これは次のように更新されました。

        // Copyright (c) 2010-2013 Diego Perini, MIT licensed
        // https://Gist.github.com/dperini/729294
        // see also https://mathiasbynens.be/demo/url-regex
        // modified to allow protocol-relative URLs
        return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( value );

ソース: https://github.com/jzaefferer/jquery-validation/blob/c1db10a34c0847c28a5bd30e3ee1117e137ca834/src/core.js#L1349

68
artfulhacker

正規表現を使用してURLを解析することは実用的ではありません。 RFC1738ルールを完全に実装すると、非常に長い正規表現が生成されます(可能な場合でも)。確かに現在の式は多くの有効なURLに失敗し、無効なURLを渡します。

代わりに:

a。実際のルールに従う実際のURLパーサーを使用します。 (私はJavaScriptについては知りません。おそらくやり過ぎでしょう。サーバー側でもできます)。または、

b。先頭または末尾のスペースを削除し、優先スキーム(通常は「http://」または「https://」)があることを確認して、そのままにします。または、

c。 URLを使用して、たとえばサーバー側からHTTP HEAD要求で送信することにより、最後にあるものを確認してください。 404または接続エラーが発生した場合は、おそらく間違っています。

urlが「 http:// wwww 」のような場合でもtrueを返します。

まあ、それは実際に完全に有効なURLです。

「wwww」などのホスト名が実際に存在するかどうかを確認する場合は、DNSで検索する以外に選択肢はありません。繰り返しますが、これはサーバー側のコードです。

47
bobince
function validateURL(textval) {
    var urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/;
    return urlregex.test(textval);
}

これは、次のようなURLに対してtrueを返します。

http://stackoverflow.com/questions/1303872/url-validation-using-javascript

または:

http://regexlib.com/DisplayPatterns.aspx?cattabindex=1&categoryId=2
33
Mohesh Mohan

また、httpおよびhttpsのURLを確認するために、rfc1738およびrfc3986に基づいたURL検証関数を作成しました。私はこのモジュラーを保持しようとしているので、それはよりよく維持され、自分の要件に適応することができます。

この記事の最後に、1行のRegExpが表示されます。

RegExpは、国際ドメインまたはIPv4番号を持つHTTPおよびHTTPS URLを受け入れます。 IPv6はまだサポートされていません。

window.isValidURL = (function() {// wrapped in self calling function to prevent global pollution

     //URL pattern based on rfc1738 and rfc3986
    var rg_pctEncoded = "%[0-9a-fA-F]{2}";
    var rg_protocol = "(http|https):\\/\\/";

    var rg_userinfo = "([a-zA-Z0-9$\\-_.+!*'(),;:&=]|" + rg_pctEncoded + ")+" + "@";

    var rg_decOctet = "(25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9]|[1-9][0-9]|[0-9])"; // 0-255
    var rg_ipv4address = "(" + rg_decOctet + "(\\." + rg_decOctet + "){3}" + ")";
    var rg_hostname = "([a-zA-Z0-9\\-\\u00C0-\\u017F]+\\.)+([a-zA-Z]{2,})";
    var rg_port = "[0-9]+";

    var rg_hostport = "(" + rg_ipv4address + "|localhost|" + rg_hostname + ")(:" + rg_port + ")?";

    // chars sets
    // safe           = "$" | "-" | "_" | "." | "+"
    // extra          = "!" | "*" | "'" | "(" | ")" | ","
    // hsegment       = *[ alpha | digit | safe | extra | ";" | ":" | "@" | "&" | "=" | escape ]
    var rg_pchar = "a-zA-Z0-9$\\-_.+!*'(),;:@&=";
    var rg_segment = "([" + rg_pchar + "]|" + rg_pctEncoded + ")*";

    var rg_path = rg_segment + "(\\/" + rg_segment + ")*";
    var rg_query = "\\?" + "([" + rg_pchar + "/?]|" + rg_pctEncoded + ")*";
    var rg_fragment = "\\#" + "([" + rg_pchar + "/?]|" + rg_pctEncoded + ")*";

    var rgHttpUrl = new RegExp( 
        "^"
        + rg_protocol
        + "(" + rg_userinfo + ")?"
        + rg_hostport
        + "(\\/"
        + "(" + rg_path + ")?"
        + "(" + rg_query + ")?"
        + "(" + rg_fragment + ")?"
        + ")?"
        + "$"
    );

    // export public function
    return function (url) {
        if (rgHttpUrl.test(url)) {
            return true;
        } else {
            return false;
        }
    };
})();

RegExpを1行で:

var rg = /^(http|https):\/\/(([a-zA-Z0-9$\-_.+!*'(),;:&=]|%[0-9a-fA-F]{2})+@)?(((25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9]|[1-9][0-9]|[0-9])(\.(25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9]|[1-9][0-9]|[0-9])){3})|localhost|([a-zA-Z0-9\-\u00C0-\u017F]+\.)+([a-zA-Z]{2,}))(:[0-9]+)?(\/(([a-zA-Z0-9$\-_.+!*'(),;:@&=]|%[0-9a-fA-F]{2})*(\/([a-zA-Z0-9$\-_.+!*'(),;:@&=]|%[0-9a-fA-F]{2})*)*)?(\?([a-zA-Z0-9$\-_.+!*'(),;:@&=\/?]|%[0-9a-fA-F]{2})*)?(\#([a-zA-Z0-9$\-_.+!*'(),;:@&=\/?]|%[0-9a-fA-F]{2})*)?)?$/;
15
TLindig

同様の状況で、私はこれで逃げました:

someUtils.validateURL = function(url) {
    var parser = document.createElement('a');
    try {
        parser.href = url;
        return !!parser.hostname;
    } catch (e) {
        return false;
    }
};

すなわち、ブラウザがあなたのためにそれをすることができるなら、なぜ車輪を発明しますか?しかし、もちろん、これはブラウザでのみ機能します。

解析されたURLには、ブラウザがどのように解釈するかを示すさまざまな部分があります。

parser.protocol; // => "http:"
parser.hostname; // => "example.com"
parser.port;     // => "8080"
parser.pathname; // => "/path/"
parser.search;   // => "?search=test"
parser.hash;     // => "#hash"
parser.Host;     // => "example.com:3000"

これらを使用すると、要件に応じて検証機能を改善できます。唯一の欠点は、相対URLを受け入れ、現在のページサーバーのホストとポートを使用することです。しかし、パーツからURLを再構成し、常に完全にAJAXサービスに渡すことにより、それを有利に使用できます。

validateURLが受け入れないものは無効なURLです。 http:\:8883はfalseを返しますが、:1234は有効であり、http://pagehost.example.com/:1234として、つまり相対パスとして解釈されます。

更新

このアプローチは、Chromeおよびその他のWebKitブラウザーでは機能しなくなりました。 URLが無効な場合でも、ホスト名には何らかの値が入力されます。 baseから取得。それでもURLの一部を解析するのに役立ちますが、検証することはできません。

独自のパーサーなしのより良いアプローチは、var parsedURL = new URL(url)を使用して例外をキャッチすることです。例参照 RL API 。すべての主要なブラウザとNodeJSでサポートされていますが、まだ実験段階です。

12
Alex Pakka

http://angularjs.org/ から見つけた最高の正規表現

var urlregex = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/;

8
nguyên

私はそれがかなり古い質問であることを知っていますが、受け入れられた答えがないため、URI.jsフレームワークを使用することをお勧めします: https://github.com/medialize/URI.js

これを使用して、try/catchブロックを使用して不正なURIを確認できます。

function isValidURL(url)
{
    try {
        (new URI(url));
        return true;
    }
    catch (e) {
        // Malformed URI
        return false;
    }
}

もちろん、 "%@"のようなものを適切な相対URIとして考慮します...したがって、URI.jsを読むことをお勧めします API より多くのチェックを実行する場合、たとえばユーザーが正しい形式の絶対URLを入力したことを確認してください。次のようにします。

function isValidURL(url)
{
    try {
        var uri = new URI(url);
        // URI has a scheme and a Host
        return (!!uri.scheme() && !!uri.Host());
    }
    catch (e) {
        // Malformed URI
        return false;
    }
}
6
Romain

これは私のために働いたものです:

function validateURL(value) {
    return /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
    }

そこから関数を呼び出してtrueまたはfalseを取得するだけです:

validateURL(urltovalidate);
3
Crisman

のようなnpmパッケージでインポートする

https://www.npmjs.com/package/valid-url

それを使用してURLを検証します。

2
ooolala
var RegExp = (/^HTTP|HTTP|http(s)?:\/\/(www\.)?[A-Za-z0-9]+([\-\.]{1}[A-Za-z0-9]+)*\.[A-Za-z]{2,40}(:[0-9]{1,40})?(\/.*)?$/);
1
SagarPPanchal

最近使用された RL API を使用できます。ブラウザのサポートはせいぜい大ざっぱです。リンクを参照してください。 new URL(str)は、無効なURLに対してTypeErrorをスローすることが保証されています。

上記のように、http://wwwwは有効なURLです。

1
amoe

より信頼性の高い正規表現をお探しの場合は、RegexLibをご覧ください。興味があると思われるページは次のとおりです。

http://regexlib.com/Search.aspx?k=url

ユーザーが入力中に表示されるエラーメッセージについては、イベントをkeydownからblurに変更すると、ユーザーが次の要素に移動したときにのみチェックされます。

1
nickf

私の解決策:

function isValidUrl(t)
{
    return t.match(/^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i)
}
1
IT Vlogs

私はグーグルで多くのURLバリデータをチェックしましたが、誰も私のために働いていません。たとえば、「aa.com」などのリンクで有効なものを確認したいです。私は、文字列のドット記号の愚かなチェックが好きです。

function isValidUri(str) {
  var dotIndex = str.indexOf('.');
  return (dotIndex > 0 && dotIndex < str.length - 2);
}

文字列の最初と最後にとどまるべきではありません(今のところ、1文字のトップレベルドメイン名はありません)。

0
alex naumov

デモ: http://jsbin.com/uzimeb/1/edit

function checkURL(value) {
    var urlregex = new RegExp("^(http|https|ftp)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&amp;%\$\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&amp;%\$#\=~_\-]+))*$");
    if (urlregex.test(value)) {
        return (true);
    }
    return (false);
}
0
Yasser

さまざまなソリューションを比較するための素晴らしいリソースを見つけました: https://mathiasbynens.be/demo/url-regex

そのページによると、diegoperiniのソリューションのみがすべてのテストに合格します。その正規表現は次のとおりです。

_^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:/[^\s]*)?$_iuS
0
Zoran P.