Проверьте, является ли строка Javascript url-адресом
есть ли способ в javascript проверить, является ли строка url-адресом?
регулярные выражения исключаются, потому что url-адрес, скорее всего, написан как stackoverflow
; то есть он может не иметь .com, www или http
17 ответов:
связанный вопрос с ответом:
в 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 locater if(!pattern.test(str)) { alert("Please enter a valid URL."); return false; } else { return true; } }
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); }
вместо того, чтобы использовать регулярное выражение, я бы порекомендовал использовать элемент привязки.
при установке
href
свойстваanchor
, установлены различные другие свойства.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-адресу, тогда значение этих вспомогательных свойств будет пустой строкой.Edit: как указано в комментариях: если используется недопустимый url-адрес, свойства текущего URL-адреса могут быть заменены.
Итак, пока вы не передаете URL текущей страницы, вы можете сделать что-то вроде:
function isValidURL(str) { var a = document.createElement('a'); a.href = str; return (a.host && a.host != window.location.host); }
вы можете попробовать использовать
URL
конструктор: если он не бросает, строка является допустимым URL:const isValidUrl = (string) => { try { new URL(string); return true; } catch (_) { return false; } }
для проверки Url с помощью javascript показано ниже
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; } }
улучшение принятого ответа...
- имеет двойной побег для обратной косой черты (\\)
- гарантирует, что домены имеют точку и расширение (. com .io.xyz)
- позволяет полное двоеточие (:) в пути, например http://thingiverse.com/download:1894343
- позволяет амперсанд ( & ) в пути, напримерhttp://en.wikipedia.org/wiki/Procter_&_Gamble
позволяет символ " @ " в пути, например https://medium.com/@techytimo
isURL(str) { var pattern = new RegExp('^(https?:\/\/)?'+ // 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); }
полагаться на библиотеки: https://www.npmjs.com/package/valid-url
import { isWebUri } from 'valid-url'; // ... if (!isWebUri(url)) { return "Not a valid url."; }
(У меня нет представителей, чтобы комментировать ValidURL пример; следовательно, опубликуйте это как ответ.)
хотя использование относительных 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-адресов.
Я использую ниже функцию для проверки URL с или без
http/https
: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); 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
вот еще один метод.
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'));
Я не могу прокомментировать сообщение, которое является самым близким #5717133, но ниже я понял, как заставить @tom-gullen regex работать.
/^(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
как уже отмечалось, идеальное регулярное выражение неуловимо, но все же кажется разумным подходом (альтернативами являются тесты на стороне сервера или новый экспериментальный URL API). Однако ответы с высоким рейтингом часто возвращают false для общих URL-адресов, но еще хуже заморозят ваше приложение / страницу в течение нескольких минут даже на такой простой строке, как
isURL('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
. Это было отмечено в некоторых комментариях, но скорее всего не ввели неверное значение, чтобы увидеть его. Висит так, что делает этот код непригоден для использования в любом серьезном приложении. Я думаю, что это из-за повторяющихся нечувствительных к регистру наборов в коде, таких как((([a-z\d]([a-z\d-]*[a-z\d])*)\.?)+[a-z]{2,}|' ...
. Выньте "я", и он не висит, но, конечно, не будет работать по желанию. Но даже с флагом ignore case эти тесты отклоняют допустимые высокие значения Юникода.лучше всего уже упоминалось:
function isURL(str) { return /^(?:\w+:)?\/\/([^\s\.]+\.\S{2}|localhost[\:?\d]*)\S*$/.test(str); }
это происходит от Github segmentio / is-url. Хорошая вещь о репозитории кода - Вы можете увидеть тестирование и любые проблемы а также тестовые строки проходят через него. Там есть ветка, которая позволит строки отсутствует протокол, как
google.com
, хотя вы, вероятно, делаете слишком много предположений тут. репозиторий был обновлен, и я не планирую пытаться поддерживать зеркало здесь. Он был разбит на отдельные тесты, чтобы избежать регулярных выражений redos который может быть использован для DOS-атак (я не думаю, что вам нужно беспокоиться об этом с JS на стороне клиента, но вам нужно беспокоиться о своей странице висит так долго, что посетитель покидает ваш сайт).есть еще один репозиторий, который я видел может быть даже лучше для isURL at dperini / regex-weburl.js, но это очень сложно. Он имеет больший тестовый список допустимых и недопустимых URL-адресов. Простой выше по-прежнему передает все положительные стороны и не может блокировать только несколько нечетных негативов, таких как
http://a.b--c.de/
а также специальные ips.что бы вы ни выбрали, запустите его через это функция, которую я адаптировал из тестов на dperini / regex-weburl.js, при использовании инструментов разработчика Вашего браузера inpector.
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:password@example.com:8080")); console.assert(isURL("http://userid:password@example.com:8080/")); console.assert(isURL("http://userid@example.com")); console.assert(isURL("http://userid@example.com/")); console.assert(isURL("http://userid@example.com:8080")); console.assert(isURL("http://userid@example.com:8080/")); console.assert(isURL("http://userid:password@example.com")); console.assert(isURL("http://userid:password@example.com/")); 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:p@example.com:5702/db")); console.assert(isURL("https://d1f4470da51b49289906b3d6cbd65074@app.getsentry.com/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"));}
а затем проверить эту строку "а".
посмотреть этот сравнение регулярных выражений isURL Матиас Байненс для получения дополнительной информации, прежде чем опубликовать, казалось бы, большое регулярное выражение.
одна функция, которую я использую для проверки URL-адреса "string":
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
можно использовать URL native API:
const isUrl = string => { try { return Boolean(new URL(string)); } catch(e){ return false; } }
вопрос задает метод проверки для url-адреса, например
stackoverflow
, без протокола или любой точки в имени хоста. Так что, это не вопрос проверки синтаксис URL-адресов, но проверить, если это действительный URL-адрес, на самом деле вызывается он.я попробовал несколько методов, чтобы узнать, существует ли url true и вызывается из браузера, но не нашел способа проверить с помощью javascript заголовок ответа вызова:
- добавление якорного элемента в порядке за стрельбу по
click()
метод.- что делает AJAX-вызов для сложных URL-адресов с
'GET'
это нормально, но имеет различные ограничения из-заCORS
политика и это не случай использованияajax
, поскольку url-адрес может быть любым вне домена моего сервера.- С помощью fetch API имеет обходной путь, подобный ajax.
- другая проблема заключается в том, что у меня есть сервер под
https
протокол и выдает исключение при вызове не безопасно URL-адреса.Итак, лучшее решение, которое я могу придумать, - это получить какой-то инструмент для выполнения
CURL
С помощью JavaScript пытается что-то вродеcurl -I <url>
. К сожалению, я не нашел ни одного и в появление невозможно. Буду признателен за любые комментарии по этому поводу.но, в конце концов, у меня есть сервер под управлением
PHP
и поскольку я использую Ajax почти для всех моих запросов, я написал функцию на стороне сервера, чтобы выполнить запрос curl там и вернуться в браузер.Что касается одного слова url на вопрос "stackoverflow" это приведет меня к
https://daniserver.com.ar/stackoverflow
, где daniserver.com.ar это мой собственный домен.
Я думаю, используя родной URL API лучше, чем сложные шаблоны регулярных выражений, как предложил @pavlo. У него есть некоторые недостатки, которые мы можем исправить с помощью дополнительного кода. Этот подход не выполняется для следующего допустимого 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; } }
The
hostname
атрибут является пустой строкой дляjavascript:void(0)
, так что это тоже работает, и вы также можете добавить верификатор IP-адреса тоже. Я хотел бы придерживаться собственного API больше всего, и надеюсь, что он начнет поддерживать все в ближайшем будущем.
Это, кажется, одна из самых сложных проблем в CS ;)
вот еще неполное решение, которое работает достаточно хорошо для меня и лучше, чем другие, которые я видел здесь. Я использую input[type=url] для этого, чтобы поддерживать IE11, иначе было бы намного проще использовать окно.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:pw@mydomain.com'), 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.