Премини към съдържанието
cutty.dev
All posts

Auto-prefix URL — дреболия, която спестява минути

cutty.dev разпознава, когато поставиш адрес без https:// и сам го добавя. Звучи тривиално. На практика това е разликата между две секунди и кликване върху „опитай отново“.

Въвеждате в полето allegro.pl. Кликвате. И какво?

В повечето скъсяватели в този момент получавате съобщение за грешка. Нещо от типа на "това не е валиден URL адрес". Защото липсва https:// отпред. И така се връщате назад, дописвате протокола, кликате отново и чак сега имате своя кратък линк.

cutty.dev не прави това. Просто сам добавя https:// и продължава напред, сякаш нищо не се е случило.

Знам как звучи. Като функция, която едва заслужава параграф, не говоря за цяла публикация. И все пак седя и пиша за това, защото точно този детайл е за мен малък манифест за това как изобщо мисля за изграждането на инструмента auto-prefix URL и цялата останала част от тези невидими улеснения.

Две секунди срещу двадесет

Да пресметнем. Наистина, с числата, защото иначе е само говорене.

Първи път: поставяш, имаш линк, затваряш прозореца. Две секунди. Може и три.

Втори път: поставяш, грешка, четеш съобщението (секунда или две, за да разбереш за какво става въпрос), дописваш протокола, кликаш отново, чак сега линкът. Петнадесет, двадесет секунди. Плюс този малък момент на раздразнение, това тихо „а да, протокола“, което не струва нищо поотделно, но се натрупва.

А сега умножете това по това колко пъти на месец поставяте някакъв адрес. При мен това са десетки. При някой, който управлява линкове професионално — стотици. Изведнъж този „заслужаващ едва споменаване“ детайл се превръща в минути на месец. На човек.

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

Какво всъщност стои под повърхността

Механизмът е тривиален и изобщо не го крия. Поставяте текст в полето. Преди нещо да бъде изпратено до сървъра, парче JavaScript проверява дали това, което сте написали, започва с някакъв протокол — http://, https://, ftp://, mailto:, каквото и да е. Ако не започва така, системата приема, че имате предвид обикновена домена и добавя https:// отпред.

На практика:

  • allegro.pl се превръща в https://allegro.pl
  • github.com/twoj-profil/projekt в https://github.com/twoj-profil/projekt
  • www.gazeta.pl в https://www.gazeta.pl

А ако протоколът вече е там, макар и странен, системата не го презаписва. Оставя го и проверява нататък какво да прави с него. http://example.com преминава (дозволено). ftp://example.com отива в кошчето, защото приемаме само http и https. А javascript:alert(1) изхвърля веднага, защото това не е адрес, а опит за инжектиране на нещо лошо (класически XSS, благодаря, не).

Защо аз го имам, а половината от пазара не

Тук става интересно, защото отговорът е малко смешен.

Стандартният начин за валидация на адрес в браузъра е конструкторът new URL(string). И този конструктор е суров. Безкомпромисен. Няма протокол — хвърля грешка. new URL("allegro.pl") просто ти връща TypeError и това е всичко.

И знаеш ли какво? Това е правилното поведение. За огромното мнозинство от приложения точно това искаш. Но във формата за съкращаване на линкове, където човек копира адреса от лентата на браузъра или от чийто-то съобщение, тази суровост се превръща от предимство в препятствие. Изведнъж инструментът, който трябва да ти пести време, ти кара да поправяш нещо, което всъщност разбира отлично.

Обоhagenieto на това е буквално няколко реда:

function sanitizeUrl(input) {
  const trimmed = input.trim();
  const hasProtocol = /^[a-z][a-z0-9+.-]*:/i.test(trimmed);
  const normalized = hasProtocol ? trimmed : "https://" + trimmed;
  // dalej leci normalna walidacja przez new URL(normalized)
}

Пет реда. Десетки секунди по-малко триене, всеки ден, за всеки, който поставя адреси. Искрено не знам защо това не е стандарт навсякъде. Подозревам, че става въпрос за това, че „URL конструкторът просто работи така“ и никой не е искал да го докосва. Инерция, а не лошо намерение.

Малко разклонение за това какво означава „стандартно“

Защото тази история с new URL() е чудесен пример за нещо по-широко. Много неща в софтуера, които се считат за „така се прави“, всъщност са „така се получи от настройките по подразбиране на някоя библиотека, която никой не е поставял под въпрос“. Strict mode на конструктора не е решение на дизайнерите на cutty или на конкуренцията — това е решение на авторите на спецификацията URL, взето в съвсем различен контекст и за съвсем различни приложения.

А след това целият пазар наследява този избор по подразбиране и го нарича „стандарт“. Имам усещането, че най-добрите продукти се раждат точно в тези места, където някой е спрял и се е запитал: чакай малко, това поведение служи ли на моя потребител, или само на моята библиотека? Най-често отговорът е: на библиотеката. И тогава си струва с пет реда да преминете към страната на човека.

Тези дреболии са повече, отколкото изглеждат

Auto-prefix е само един от многобройните такива елементи, които няма да намерите в нито един списък с функции. Защото ако бъдат изброени там, всеки поотделно ще изглежда смешно малък:

  • премахване на интервалите преди валидация, за да не развали случайният интервал в края на поставения адрес всичко
  • запазване на якора, т.е. #section в https://example.com/page#section не изчезва след съкращаването
  • параметрите на заявката (?utm_source=test) преминават изцяло, нищо не се прекъсва по пътя
  • домейни с полски символи, źdźbło.pl, автоматично се превръщат в punycode
  • полските букви във собствения завършек се заменят с ASCII (różowy-link става rozowy-link)
  • опасни протоколи — javascript:, data:, file: — отхвърляне с конкретен, разбираем съобщение

(Все още се планира автоматично пренасочване на http:// към https://, когато целевият сървър поддържа криптиране. Това все още не работи в реално време, така че няма да се преструвам.)

Всеки от тези детайли спестява на някого пет, десет, тридесет секунди и едно въздъхване. Поотделно – нищо. Заедно това е разликата между „работи ОК“ и „харесвам да го използвам“.

Какво бих искал да добавя още

Списък с желания за бъдещето, защото мисленето за това просто ми носи удоволствие:

  • интелигентно поставяне — откриване на адрес, скрит в средата на изречението, и извличане само на самия URL между думите
  • масово поставяне — списък с адреси, по един на ред, и автоматично създаване на отделен кратък линк за всеки от тях
  • предлагани завършващи части — предлагане на три брандирани slug-а за избор въз основа на заглавието на целевата страница
  • Open Graph преглед веднага след поставянето, още преди да кликнете „съкрати“

Всяко от това отново е „петредова функция, която изглежда като нищо“. А всички заедно? Това е точно границата между инструмента, който е приличен, и този, към който се обръщаш всеки ден без колебание. Ако искаш да видиш как работи в момента, постави в cutty.dev каквото и да е без протокол — allegro.pl, github.com, news.ycombinator.com — и виж, че нищо не ти пречи на пътя.

Накрая, малко лично

Дълго време мислех, че продуктите печелят с големи функционалности. С това едно впечатляващо нещо, което може да се покаже на слайд и за което хората ще пишат. И да, понякога е така.

Колкото по-дълго изграждам cutty, толкова по-силно усещам, че лоялността на потребителя се ражда другаде — в тези стотици микросекунди, които никой не забелязва съзнателно. Не помниш, че инструментът сам е добавил https://. Помниш само общото впечатление, че „по някакък начин се използва добре“, „не дразни“. Това впечатление не идва от нищото. То се състои от десетки петредови решения, които никой не би защитил поотделно пред себе си като „струващи времето“.

Може би точно в това е същността на занаята. Не в този един голям жест, а в упоритостта да заставаш отново и отново на страната на човека пред формата — дори и да става въпрос за жалките две секунди. А ти? Какво те ядоса напоследък в някой инструмент, толкова дребно, че дори е срамувателно да се признае? Защото обикновено точно там се крие най-добрата работа за вършене.