2012-01-09 1 views
0

Я пытаюсь создать средство проверки URL-адресов для небольшого приложения-закладки.URL-идентификатор: если http: // не вводится, введите его динамически

Я сделал валидатор, чтобы принять, так что он принимает то, что должно быть действительным:

http://example.com 
http://www.examples.com 
http://www.example.com 
ftp://www.example.com 
ftp://cdn.example.com/ 
etc. 

Теперь, как многие из нас в реальной жизни мы, как правило, не вводите HTTP: // для веб-сайта, так что я хотите, когда пользователь вводит что-либо без http: //, https: // или ftp: //, чтобы передать http: // по умолчанию. Обратите внимание, что я не хочу передавать его на вход, но на бэкэнд.

Так что для моего примера я это:

$("#in").on('keyup', function() {  
    var url = $('#in').val(); 

    var match = /^(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})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/ 


    if (match.test(url)) { 
     console.log("URL OK") 

    } else { 
     console.log("URL invalid") 

    } 

}); 

Если HTTP: // не набран, передать его на console.log, чтобы показать, как действительный URL.

Я не уверен, что это хорошая практика, так как это может закончиться множеством ошибок, но это единственный способ, которым я мог бы подумать, что в итоге я попаду на сайт http: //. Я не могу заставить пользователей вводить http: // по каждой закладке.

Также обратите внимание, что я не хочу использовать какие-либо плагины.

Пожалуйста, дайте мне знать вашу мысль об этом.

Благодаря

ответ

0

Предполагая, что ваш матч действует ...

$("#in").on('keyup', function() {  
    var url = $('#in').val(); 

    var match = /^(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})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/; 

    var noprotocolmatch = /^(((([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})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/; 

    if (match.test(url)) { 
     console.log("URL OK with protocol"); 

    } else if (noprotocolmatch.test(url)) { 
     console.log("URL OK without protocol"); 
     url = 'http://'+url; 

    } else { 
     console.log("URL invalid") 

    } 

}); 

Эффективно, если URL не удается, мы стараемся соответствовать его от второй части, по крайней мере, если она соответствует, но не попадает в протокол мы добавьте его, и если все провалится, оно недействительно.

Или, как это, с дополнительным протоколом в первом матче и просто проверка существования протокола в два шага:

$("#in").on('keyup', function() {  
    var url = $('#in').val(); 

    var match = /^((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})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/; 
    var protomatch = /^(https?|ftp):\/\/(.*)/; 

    if (match.test(url)) { 
     console.log("URL OK"); 

     if(!protomatch.test(url)) 
      url = 'http://'+url; 

    } else { 
     console.log("URL invalid") 

    } 

}); 
+0

спасибо. То, что я искал. Считаете ли вы, что это хорошая практика? Я думал, что это закончится множеством ошибок? – jQuerybeast

+0

Если это реализовано чистым способом, это не очень подвержено ошибкам, но вы можете захотеть провести некоторое исследование по регулярному выражению url, в этом есть много разных вариантов ...С другой стороны, вы можете захотеть сделать это на своем сервере, чтобы быть уверенным, поскольку не можете быть уверены, что в этом нет вредоносного кода, так как это управляемый клиентом код. В любом случае вам нужно будет проверить возможные проблемы безопасности на сервере, поэтому почему бы не фильтровать его там в первую очередь. – bardiir

+0

Закладки основаны на localstorage, поэтому ничего не происходит с моего сервера. Я занимался исследованиями для проверки правильности URL и вот почему я оказался в этом длинном regExp. Дело в том, что если кто-то попытается найти или добавить багги URL, он добьется этого. Помимо этого, я считаю, что пользователи получат реальные URL-адреса. – jQuerybeast

0

Первое: Bind по форме представить и не на keyup

Проверка URL-адреса на каждом шаге ключа крайне неэффективна, так как вам нужно только проверить URL-адрес до, который он отправляет на сервер - это на форме submit. Поэтому использовать этот обработчик событий вместо:

$('FORM').on('submit', function() { 
if (!url_is_valid()) { 
    return false; // Cancel form submission when URL isn't valid. 
        // You'll need to display an error message as well. 
} 
}); 

Ваш URL разборе/проверка будет выполняться только один раз на странице представить, а несколько раз в секунду (в зависимости от скорости набора текста).

Второе:

Также обратите внимание, что я не хочу использовать какие-либо плагинов.

Почему нет? Разбор URI в JavaScript - это solved problem. Не изобретать колесо повторно?

+0

Ключ вверх для цели тестирования и в основном для stackoverflow. Поскольку я и пользователи могут видеть результат быстрее. И нет, я не хочу использовать их и не буду использовать какие-либо плагины. 1 лишняя строка из ответа бардира спасла мне 1263 строки кода ужасного плагина. – jQuerybeast

+0

Что бы ни делало для вас, важно. Мне кажется интересным, что вы используете jQuery, который работает в режиме 9000+ LOC, даже если вы вряд ли используете даже 5% функций jQuery, поэтому мне кажется, что корабль уже отплыл. – leepowers