Μετάβαση στο περιεχόμενο
cutty.dev
All posts

Auto-prefix URL — ένα μικρό πράγμα που εξοικονομεί λεπτά

το cutty.dev αναγνωρίζει όταν επικολλήσεις μια διεύθυνση χωρίς https:// και την προσθέτει αυτόματα. Ακούγεται ασήμαντο. Στην πράξη, είναι η διαφορά μεταξύ δύο δευτερολέπτων και ενός κλικ στο 'δοκιμάστε ξανά'.

Πληκτρολογείτε στο φόρμα allegro.pl. Κλικάρετε. Και τι;

Στις περισσότερες υπηρεσίες συντόμευσης εμφανίζεται εκείνη τη στιγμή ένα μήνυμα σφάλματος. Κάτι σαν "αυτή δεν είναι μια έγκυρη διεύθυνση URL". Επειδή λείπει το https:// στην αρχή. Έτσι επιστρέφεις πίσω, προσθέτεις το πρωτόκολλο, κάνεις κλικ ξανά, και μόνο τώρα έχεις τον σύνδεσμό σου σε σύντομη μορφή.

cutty.dev δεν το κάνει αυτό. Απλώς προσθέτει μόνο του το https:// και συνεχίζει κανονικά, σαν να μην ήταν τίποτα.

Ξέρω πώς ακούγεται. Όπως ένα feature που μόλις αξίζει μια παράγραφο, πό遑ως ολόκληρο άρθρο. Κι όμως κάθομαι και γράφω γι' αυτό, γιατί ακριβώς αυτή η λεπτομέρεια είναι για μένα ένα μικρό manifesto για το πώς σκέφτομαι γενικά την κατασκευή του εργείου auto-prefix URL και όλων των υπόλοιπων αόρατων διευκολύνσεων.

Δύο δευτερόλεπτα εναντίον είκοσι

Ας υπολογίσουμε. Πραγματικά, με τους αριθμούς, γιατί αλλιώς είναι μόνο λόγια.

Πρώτη διαδρομή: κάνεις επικόλληση, έχεις το σύνδεσμο, κλείνεις το παράθυρο. Δύο δευτερόλεπτα. Ίσως τρία.

Δεύτερη διαδρομή: κάνεις επικόλληση, σφάλμα, διαβάζεις το μήνυμα (μία ή δύο δευτερόλεπτα για να καταλάβεις τι συμβαίνει), προσθέτεις το πρωτόκολλο, κάνεις κλικ άλλη μια φορά, μόνο τώρα το link. Δεκαπέντε, είκοσι δευτερόλεπτα. Συν σε αυτό εκείνη τη μικρή στιγμή εκνευρισμού, αυτό το σιωπηλό "α ναι, πρωτόκολλο", που δεν κοστίζει τίποτα ξεχωριστά, αλλά συσσωρεύεται.

Και τώρα πολλαπλασιαστε αυτό με το πόσες φορές τον μήνα επικολλήτε κάποια διεύθυνση. Εγώ το κάνω δεκάδες φορές. Κάποιος που διαχειρίζεται συνδέσμους επαγγελματικά — εκατοντάδες. Ξαφνικά αυτή η "σχεδόν αμελητέα" λεπτομέρεια συσσωρεύεται σε λεπτά τον μήνα. Αντίστοιχα ανά άτομο.

Αυτή είναι ακριβώς αυτή η αριθμητική που οι περισσότεροι άνθρωποι αγνοούν, επειδή κάθε μεμονωμένη περίπτωση φαίνεται πολύ μικρή για να σας απασχολήσει.

Τι είναι αυτό που βρίσκεται στην πραγματικότητα από κάτω

Ο μηχανισμός είναι απλοϊκός και δεν το κρύβω καθόλου. Επικολλήσατε το κείμενο στο πεδίο. Πριν οποιοδήποτε πράγμα σταλεί στον διακομιστή, ένα κομμάτι JavaScript ελέγχει αν αυτό που πληκτρολογήσατε ξεκινά με κάποιο πρωτόκολλο — http://, https://, ftp://, mailto:, οτιδήποτε. Αν δεν ξεκινά έτσι, το σύστημα υποθέτει ότι εννοείτε έναν απλό κατάλογο (domain) και προσθέτει το 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 και τέλος.

Και ξέρεις τι; Αυτή είναι η σωστή συμπεριφορά. Για την overwhelming πλειονότητα των εφαρμογών, ακριβώς αυτό θέλεις. Αλλά σε μια φόρμα συρρίκνωσης συνδέσμων, όπου ο χρήστης αντιγράφει τη διεύθυνση από τη γραμμή περιήγησης ή από κάποιο μήνυμα, αυτή η αυστηρότητα μετατρέπεται από πλεονέκτημα σε εμπόδιο. Ξαφνικά, ένα εργαλείο που προορίζεται να σου γλιτώσει χρόνο, σε αναγκάζει να διορθώνεις κάτι που στην πραγματικότητα καταλαβαίνει τέλεια.

Η παράκαμψη αυτού είναι κυριολεκτικά λίγες γραμμές:

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 constructor λειτουργεί έτσι απλά" και κανείς δεν ήθελε να το αγγίξει. Αδράνεια, όχι κακή πρόθεση.

Μια μικρή παρενέργεια για το τι σημαίνει "κανονικά"

Γιατί αυτή η ιστορία με το new URL() είναι ένα εξαιρετικό παράδειγμα κάτι ευρύτερου. Πολλά πράγματα στο λογισμικό που θεωρούνται "έτσι γίνεται", στην πραγματικότητα είναι "έτσι προέκυψε από τις προεπιλεγμένες ρυθμίσεις κάποιας βιβλιοθήκης, την οποία κανείς δεν αμφισβήτησε". Το strict mode του κατασκευαστή δεν είναι μια απόφαση των σχεδιαστών του cutty ή του ανταγωνισμού — είναι μια απόφαση των συντακτών της προδιαγραφής URL, η οποία λήφθηκε σε ένα εντελώς διαφορετικό πλαίσιο, για εντελώς διαφορετικές χρήσεις.

Αργότερα ολόκληρη η αγορά κληρονομεί αυτή την προεπιλεγμένη επιλογή και την αποκαλεί "πρότυπο". Έχω την αίσθηση ότι τα καλύτερα προϊόντα γεννιούνται ακριβώς σε εκείνα τα σημεία όπου κάποιος σταμάτησε και αναρωτήθηκε: στιγμιά, αυτή η συμπεριφορά εξυπηρετεί τον χρήστη μου ή μόνο τη βιβλιοθήκη μου; Συνήθως η απάντηση είναι: τη βιβλιοθήκη. Και τότε αξίζει να μεταβείτε στην πλευρά του ανθρώπου με πέντε γραμμές κώδικα.

Αυτά τα λεπτομέρεια είναι περισσότερα από όσα φαίνονται


Το Auto-prefix είναι μόνο ένα από τα πολλά τέτοια στοιχεία που δεν θα βρείτε σε καμία λίστα λειτουργιών. Γιατί αν τα περιγράφαμε εκεί, το καθένα ξεχωριστά θα φαινόταν αστεία μικρό:

  • αφαίρεση κενών πριν από τον έλεγχο εγκυρότητας, ώστε ένα τυχαίο κενό στο τέλος της εισαχθείς διεύθυνσης να μην καταστρέψει τα πάντα
  • διατήρηση του αγκύρου, δηλαδή το #section στο https://example.com/page#section δεν εξαφανίζεται μετά την περικοπή
  • τα παρα параметры ερωτήματος (?utm_source=test) μεταφέρονται ολόκληρα, τίποτα δεν κόβεται στη διαδρομή
  • domains με πολωνικούς χαρακτήρες, το źdźbło.pl, μετατρέπονται αυτόματα σε punycode
  • πολωνικοί χαρακτήρες στο δικό σας slug αντικαθίστανται με ASCII (różowy-link γίνεται rozowy-link)
  • επικίνδυνα πρωτόκολλα — javascript:, data:, file: — απορρίπτονται με ένα συγκεκριμένο, κατανοητό μήνυμα

(Σχεδιάζεται ακόμη η αυτόματη αναβάθμιση από http:// σε https://, όταν ο προοριστικός διακομιστής υποστηρίζει κρυπτογράφηση. Αυτό δεν λειτουργεί ακόμα στην πράξη, επομένως δεν θα προσπαθήσω να το παρουσιάσω ως λειτουργικό.)

Κάθε ένα από αυτά τα λεπτομέρεια εξοικονομεί σε κάποιον πέντε, δέκα, τριάντα δευτερόλεπτα και μια ανάσα. Από μόνο του τίποτα. Μαζί αποτελούν τη διαφορά μεταξύ του "λειτουργεί ΟΚ" και του "μου αρέσει να το χρησιμοποιώ".

Τι θα ήθελα να προσθέσω ακόμη

Λίστα επιθυμιών για το μέλλον, γιατί η σκέψη γι' αυτό μου φέρνει απλά χαρά:

  • έξυπνο επικόλληση — εντοπισμός διεύθυνσης κρυμμένης μέσα σε μια πρόταση και εξαγωγή μόνο του URL ανάμεσα στις λέξεις
  • μαζική επικόλληση — λίστα διευθύνσεων, μία ανά γραμμή, και άμεση δημιουργία ξεχωριστού σύντομου συνδέσμου για κάθε μία
  • προτεινόμενες καταλήξεις — πρόταση τριών επιλογών για το slug με βάση τον τίτλο της προοριστικής σελίδας
  • προεπισκόπηση Open Graph αμέσως μετά την επικόλληση, ακόμα και πριν πατήσετε το "συντόμευση"

Κάθε ένα από αυτά είναι και πάλι μια "σ funkciά πέντε γραμμών που δεν φαίνεται να κάνει τίποτα". Και όλα μαζί; Αυτή ακριβώς είναι η διάκριση μεταξύ ενός εργαλείου που είναι εντάξει, και ενός τέτοιου που χρησιμοποιείς καθημερινά χωρίς δεύτερη σκέψη. Αν θέλεις να δεις πώς λειτουργεί τώρα, επικόλλησε στο cutty.dev οτιδήποτε χωρίς πρωτόκολλο — allegro.pl, github.com, news.ycombinator.com — και δες ότι δεν σου βάζει καμία εμπόδιο στον δρόμο.

Τέλος, λίγο προσωπικά

Πίστευα για πολύ καιρό ότι τα προϊόντα κερδίζουν με μεγάλες λειτουργίες. Με εκείνο το ένα εντυπωσιακό πράγμα, που μπορεί να παρουσιαστεί σε μια διαφάνεια και για το οποίο θα γράψουν οι άνθρωποι. Και ναι, μερικές φορές είναι έτσι.

Όσο περισσότερο χτίζω τα cutty, τόσο πιο έντονα νιώθω ότι η αφοσίωση του χρήστη γεννιέται κάπου αλλού — σε αυτά τα εκατοντάδες μικροδευτερόλεπτα που κανείς δεν προσέχει συνειδητά. Δεν θυμάσαι ότι το εργαλείο πρόσθεσε μόνο του το https://. Θυμάσαι μόνο την γενική εντύπωση ότι "χρησιμοποιείται αρκετά καλά", "δεν εκνευρίζει". Αυτή η εντύπωση δεν προκύπτει από το πουθενά. Αποτελείται από δεκάδες πεντηγραμμές αποφάσεις, τις οποίες κανείς δεν θα υπερασπιστόταν μεμονωμένα ως "αξίες του χρόνου".

Ίσως ακριβώς σε αυτό έγκειται η τέχνη. Όχι σε αυτή την μία μεγάλη κίνηση, αλλά στην επιμονή να στέκεσαι ξανά και ξανά στο μέρος του ανθρώπου μπροστά σε μια φόρμα — ακόμη και αν πρόκειται για δύο ασημάντες δευτερόλεπτα. Και εσύ; Τι σε εξοργήθηκε πρόσφατα σε κάποιο εργαλείο τόσο μικρό, που νωγκόμαστε να το παραδεχτούμε; Γιατί συνήθως ακριβώς εκεί κρύβεται η καλύτερη δουλειά που πρέπει να γίνει.