it-swarm.com.ru

Попытка проверить URL с помощью JavaScript

Я хочу проверить 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-адреса, пока он не совпадет с регулярным выражением, и вернет true, даже если URL-адрес имеет вид "http://wwww".

Я ценю ваши предложения.

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*)[email protected])?(?:(?!(?: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

67
artfulhacker

Непрактично разбирать URL с помощью регулярных выражений. Полная реализация правил RFC1738 привела бы к чрезвычайно длинному регулярному выражению (при условии, что это даже возможно). Конечно, ваше текущее выражение не может использовать многие действительные URL-адреса и передает недействительные.

Вместо:

а. используйте правильный анализатор URL, который на самом деле следует реальным правилам. (Я не знаю ни одного для JavaScript; это, вероятно, было бы излишним. Вы могли бы сделать это на стороне сервера, хотя). Или же,

б. просто обрежьте все начальные или конечные пробелы, затем убедитесь, что у вас есть одна из ваших предпочтительных схем спереди (обычно «http: //» или «https: //»), и оставьте это в этом. Или же,

с. попытайтесь использовать URL-адрес и посмотрите, что находится в конце, например, отправив ему запрос HTTP HEAD со стороны сервера. Если вы получаете 404 или ошибку соединения, это, вероятно, неправильно.

он возвращает true, даже если URL-адрес что-то вроде " http: // wwww ".

Ну, это действительно совершенно правильный 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);
}

Это может вернуть true для таких URL, как:

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

или же:

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

Я также написал функцию проверки URL на основе rfc1738 и rfc3986 для проверки URL-адресов http и https. Я стараюсь держать этот модульный, чтобы его можно было лучше поддерживать и адаптировать к собственным требованиям.

RegExp в одной строке показано в конце этого поста.

RegExp принимает HTTP и HTTPS URL с некоторым международным доменом или номером IPv4. 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 в одну строку:

var rg = /^(http|https):\/\/(([a-zA-Z0-9$\-_.+!*'(),;:&=]|%[0-9a-fA-F]{2})[email protected])?(((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) и перехватывать исключения. Смотрите, например URL 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

Вы можете использовать его для проверки неправильного URI с помощью блока try/catch:

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

Вы можете использовать URL API , который недавно был стандартным. Поддержка браузеров в лучшем случае схематична, смотрите ссылку. new URL(str) гарантированно выбрасывает TypeError для недействительных URL.

Как указано выше, 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
Dung Vu

Я проверил много валидаторов URL в Google, и никто не работает для меня. Например, я хотел бы видеть действительные ссылки типа «aa.com». Мне нравится глупая проверка на наличие точки в строке.

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

Он не должен оставаться в начале и конце строки (сейчас у нас нет доменных имен верхнего уровня с одним символом). 

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*)[email protected])?(?:(?!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.