Комментарии 30
А как быть, если мы используем browserify, webpack? Без полифилов для нодовых модулей, но с module.exports?
+2
var isNode = typeof process != 'undefined' && {}.toString.call(process) == '[object process]';
0
На самом деле это неправильно) Нас не интересует нода это или нет, нас интересует, можем ли мы разобрать ссылку при помощи DOM.
Как-то так:
Как-то так:
if (typeof document == 'object' && document.createElement) {
url = document.createElement('a');
url.href = str;
return url;
} else {
return url.parse(str);
}
0
На самом деле, нет никакой разницы, Node.js это или нет, так как browserify предоставляет браузерные версии стандартных модулей, в том числе и url, так что и смысла извращаться нет. Я привёл этот код только потому, как в статье предлагается 2 неверных способа определить, нода это или нет. Ваш вариант не более правильный, потому как в окружении без dom также может отсутствовать и модуль url.
+1
Мой вариант может неправильный практически, но идеологически именно такой вариант и должен использоваться — хотите использовать сомнительную фичу, то проверьте её существование, а не платформу.
+6
На ноде модуль url есть из коробки и определение платформы достаточный фичадетект для его использования без нежелательных последствий. В браузере же его подключение добавит в сборку лишний здоровый модуль (привет варианту из статьи). А результат и моего, и вашего вариантов один.
0
В статье показан workaround, как можно использовать функционал парсинга урлов, но этот функционал ни разу не является надежным. Т.к. на серверной стороне зависит от специфичного для Node.js окружения, а на клиентской стороне от специфичной фичи браузера. Такой функционал нельзя распространять в виде npm-модуля, в виде кода своего приложения сколько угодно.
0
url = document.createElement('a');Это не очень хороший способ вытащить данные о URL. document.createElement — довольно медленная операция, и если вам надо распарсить 10000 ссылок в цикле, то это может ощутимо подвесить браузер.
url.href = str;
return url;
Я понимаю, что это только пример, но кто-то может захотеть использовать его в реальной жизни. Нехорошо писать такие примеры.
0
Не так уж и медленно — на 100 тысяч фаерфокс (на amd fx 6100 3.3GHz) тратит меньше секунды (800 мс)
jsfiddle.net/fh21gu0a/
p.s. По мне так отличнейший способ не изобретать своего велосипеда. Мало того, если вдруг будут внесены какие то изменения в стандарт url, то браузер поддержку обновит, а вот ваш сайт лет через 5-10 никто обновлять не будет!
jsfiddle.net/fh21gu0a/
p.s. По мне так отличнейший способ не изобретать своего велосипеда. Мало того, если вдруг будут внесены какие то изменения в стандарт url, то браузер поддержку обновит, а вот ваш сайт лет через 5-10 никто обновлять не будет!
+4
А зачем вообще делать document.createElement в цикле?
0
Отвечу на это примером из жизни. Пару лет назад, когда я был моложе и зеленее, для работы с большими таблицами на клиенте я воспользовался одной библиотекой, название которой уже не помню. Но что мне запомнилось, так это то, что она начинала нещадно тормозить при выводе текста, которому надо было убирать тэги. Данных было много, порядка 5000 строк по 10 ячеек в строке, и это был единственный юзкейс при котором тормоза становились неприемлемыми.
Расчехлив профилировщик я обнаружил, что очистка от тэгов производилась как-то так
Вы спрашиваете, зачем это делать в цикле. Незачем, если это пример. Но в реальной жизни кто-нибудь может засунуть это в функцию
Расчехлив профилировщик я обнаружил, что очистка от тэгов производилась как-то так
var span = document.createElement("span");
span.innerHTML = str;
var filtered_str = span.innerText;
Это и было самым ресурсоёмким местом. С тех пор я помню, что создание элементов DOM — не самая быстрая операция, можно и побыстрее. Вы спрашиваете, зачем это делать в цикле. Незачем, если это пример. Но в реальной жизни кто-нибудь может засунуть это в функцию
-3
1) если вам нужно распарсить 100500 URL-адресов в браузере, то вам свинья не товарищ
2) никто для такой узкой задачи не запрещает сделать document.createElement лишь раз
2) никто для такой узкой задачи не запрещает сделать document.createElement лишь раз
0
В браузере, к сожалению, нет похожего метода
url.spec.whatwg.org/#api
developer.mozilla.org/en-US/docs/Web/API/URL/URL
github.com/arv/DOM-URL-Polyfill
+3
Примерно раз в год, кто-то изобретает этот велосипед, и спешит поделиться с хабром.
+6
ftp://user#1:2@[ff:fe::1]:3128/foo/bar?q#hash
Съест?
+1
Прошу прощения за, возможно, глупый вопрос, а что такое "#1:2"?
0
> user#1
В данном случае все что после # будет фрагментом, по rfc3986 символ # невозможен нигде кроме как во фрагменте.
В данном случае все что после # будет фрагментом, по rfc3986 символ # невозможен нигде кроме как во фрагменте.
+1
authority = [ userinfo "@" ] host [ ":" port ]
userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
Да, вы правы. Меняю задачу:
userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
Да, вы правы. Меняю задачу:
ftp://user!&1:$&*;=3@[ff:fe::1]:3128/foo/bar?q#hash
+1
❯ node -p 'require("url").parse("ftp://user!&1:$&*;=3@[ff:fe::1]:3128/foo/bar?q#hash")'
{ protocol: 'ftp:',
slashes: true,
auth: 'user!&1:$&*;=3',
host: '[ff:fe::1]:3128',
port: '3128',
hostname: 'ff:fe::1',
hash: '#hash',
search: '?q',
query: 'q',
pathname: '/foo/bar',
path: '/foo/bar?q',
href: 'ftp://user!%261:%24%26*%3B%3D3@[ff:fe::1]:3128/foo/bar?q#hash' }
+1
github.com/petkaantonov/urlparser — вот кстати еще более быстрый парсер урлов, без регулярки. Сейчас это вроде висит как PR в io.js с тегом «на повестке дня».
0
Писал свой с поддержкой сложного query
Демка: runkit.com/pxyup/5c336aed02ce8e00124ee50d
github.com/PxyUp/uri-parse-lib
Демка: runkit.com/pxyup/5c336aed02ce8e00124ee50d
github.com/PxyUp/uri-parse-lib
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Простой разбор URL с помощью изоморфного Javascript