ข้ามไปยังเนื้อหาหลัก
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 แบบคลาสสิก ขอบคุณ แต่ไม่เอาดีกว่า)

ทำไมฉันถึงมีสิ่งนี้ แต่คนอีกครึ่งหนึ่งของตลาดกลับไม่มี

ตรงนี้เริ่มน่าสนใจแล้ว เพราะคำตอบมันค่อนข้างตลกนิดหน่อย

วิธีมาตรฐานในการตรวจสอบความถูกต้องของที่อยู่ (address) ในเบราว์เซอร์คือคอนสตรัคเตอร์ new URL(string) และคอนสตรัคเตอร์นี้ก็เข้มงวดมาก ไม่ประนีประนอม หากไม่มีโปรโตคอล — มันจะโยนข้อผิดพลาดออกมา new URL("allegro.pl") จะคืนค่าเพียงแค่ TypeError และจบแค่นั้น

และคุณรู้อะไรไหม? นี่คือพฤติกรรมที่ถูกต้อง สำหรับแอปพลิเคชันส่วนใหญ่แล้วนี่คือสิ่งที่คุณต้องการเลย แต่ในฟอร์มสำหรับย่อลิงก์ ที่ซึ่งคนเราคัดลอกที่อยู่จากแถบเบราว์เซอร์หรือจากข้อความของใครบางคน ความเข้มงวดนี้จะเปลี่ยนจากข้อดีกลายเป็นอุปสรรค ทันใดนั้น เครื่องมือที่ควรจะช่วยประหยัดเวลาให้คุณ กลับสั่งให้คุณต้องตามแก้ไขสิ่งที่มันเองก็เข้าใจได้อย่างดีเยี่ยมอยู่แล้ว

การหลีกเลี่ยงสิ่งนี้ใช้เพียงไม่กี่บรรทัดเท่านั้น:

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)
}

ห้าบรรทัด ลดแรงเสียดทานไปได้สิบกว่าวินาทีต่อวัน สำหรับทุกคนที่ต้องคัดลอกและวางที่อยู่ (address) บอกตามตรงว่าฉันไม่รู้เลยว่าทำไมสิ่งนี้ถึงไม่ใช่มาตรฐานในทุกๆ ที่ ฉันสงสัยว่ามันเป็นเพราะ "URL constructor มันทำงานแบบนั้นอยู่แล้ว" และไม่มีใครอยากจะเข้าไปแตะต้องมัน ความเฉื่อยชา ไม่ใช่ความไม่เต็มใจ

ข้อสังเกตเล็กน้อยเกี่ยวกับความหมายของคำว่า "ตามมาตรฐาน"

เพราะเรื่องราวเกี่ยวกับ new URL() นี้เป็นตัวอย่างที่ยอดเยี่ยมของสิ่งที่กว้างกว่านั้น สิ่งต่างๆ มากมายในซอฟต์แวร์ที่ถูกมองว่า "มันต้องทำแบบนี้" แท้จริงแล้วคือ "มันออกมาเป็นแบบนี้เพราะการตั้งค่าเริ่มต้นของไลบรารีบางอย่างที่ไม่มีใครโต้แย้ง" การกำหนด strict mode ของ constructor ไม่ใช่การตัดสินใจของผู้ออกแบบ cutty หรือคู่แข่ง — แต่มันคือการตัดสินใจของผู้เขียนข้อกำหนด URL ซึ่งถูกตัดสินใจในบริบทที่แตกต่างออกไปโดยสิ้นเชิง สำหรับการใช้งานที่แตกต่างออกไปโดยสิ้นเชิง

และหลังจากนั้นทั้งตลาดก็รับเอาตัวเลือกเริ่มต้นนี้ไปใช้และเรียกมันว่า "มาตรฐาน" ฉันมีความรู้สึกว่าผลิตภัณฑ์ที่ดีที่สุดมักจะถือกำเนิดขึ้นในจุดที่ใครบางคนหยุดคิดและตั้งคำถามว่า: เดี๋ยวก่อนนะ พฤติกรรมนี้ทำเพื่อผู้ใช้งานของฉัน หรือแค่เพื่อ library ของฉันกันแน่? ส่วนใหญ่มักจะได้คำตอบว่า: เพื่อ library และเมื่อนั้น มันก็คุ้มค่าที่จะใช้โค้ดเพียงห้าบรรทัดเพื่อเปลี่ยนกลับมาให้ความสำคัญกับมนุษย์

รายละเอียดเล็กน้อยเหล่านี้มีมากกว่าที่เห็น

Auto-prefix เป็นเพียงหนึ่งในหลายๆ องค์ประกอบที่คุณจะไม่พบในรายการฟีเจอร์ใดๆ เพราะถ้าหากใส่พวกมันลงไปในนั้น แต่ละอย่างจะดูเล็กจนน่าตลก:

  • ตัดช่องว่างก่อนการตรวจสอบ เพื่อไม่ให้ช่องว่างที่อาจเกิดขึ้นโดยไม่ได้ตั้งใจที่ท้าย URL ที่วางมาทำให้เกิดข้อผิดพลาด
  • รักษา anchor ไว้ กล่าวคือ #section ใน https://example.com/page#section จะไม่หายไปหลังจากย่อส่วน
  • query parameters (?utm_source=test) จะถูกส่งผ่านไปทั้งหมด โดยไม่มีการตัดทิ้งระหว่างทาง
  • โดเมนที่มีอักขระภาษาโปแลนด์ เช่น źdźbło.pl จะถูกแปลงเป็น punycode โดยอัตโนมัติ
  • ตัวอักษรภาษาโปแลนด์ในส่วนท้าย (slug) จะถูกเปลี่ยนเป็น ASCII (różowy-link กลายเป็น rozowy-link)
  • โปรโตคอลที่ไม่ปลอดภัย — javascript:, data:, file: — จะถูกปฏิเสธพร้อมด้วยข้อความแจ้งเตือนที่เฉพาะเจาะจงและเข้าใจง่าย

(ยังมีการวางแผนที่จะเปลี่ยน http:// เป็น https:// โดยอัตโนมัติ เมื่อเซิร์ฟเวอร์ปลายทางรองรับการเข้ารหัส ซึ่งในขณะนี้ระบบดังกล่าวยังไม่ได้ใช้งานจริง ดังนั้นผมจะไม่แสร้งว่ามันทำงานได้)

รายละเอียดแต่ละอย่างเหล่านี้ช่วยประหยัดเวลาให้ใครบางคนได้ห้า สิบ หรือสามสิบวินาที และลดการถอนหายใจลงได้หนึ่งครั้ง หากมองแยกกันมันไม่มีค่าอะไรเลย แต่เมื่อรวมกันแล้ว มันคือความแตกต่างระหว่าง "ใช้งานได้โอเค" กับ "ฉันชอบที่จะใช้งานมัน"

สิ่งที่ฉันอยากจะทำเพิ่มเติม

รายการสิ่งที่อยากทำในอนาคต เพราะการได้คิดถึงเรื่องนี้ทำให้ฉันมีความสุข:

  • การวางแบบอัจฉริยะ — ตรวจจับที่อยู่ซึ่งซ่อนอยู่ในประโยคและดึงเฉพาะ URL ออกมาจากระหว่างคำ
  • การวางแบบกลุ่ม — รายการที่อยู่ หนึ่งรายการต่อหนึ่งบรรทัด และสร้างลิงก์สั้นแยกกันทันทีสำหรับแต่ละรายการ
  • ส่วนท้ายที่แนะนำ — เสนอ slug ที่เป็นเอกลักษณ์ให้เลือกสามแบบ โดยอิงจากชื่อของหน้าปลายทาง
  • ตัวอย่าง Open Graph ทันทีหลังจากวาง ก่อนที่คุณจะคลิก "ย่อ"

แต่ละอย่างล้วนเป็น "ฟังก์ชันห้าบรรทัดที่ดูเหมือนไม่มีอะไร" อีกครั้ง และเมื่อรวมกันทั้งหมดล่ะ? นั่นคือเส้นแบ่งระหว่างเครื่องมือที่แค่พอใช้ได้ กับเครื่องมือที่คุณหยิบมาใช้ทุกวันโดยไม่ต้องหยุดคิด หากคุณต้องการเห็นว่ามันทำงานอย่างไรในตอนนี้ ให้ลองวางอะไรก็ได้ที่ไม่มีโปรโตคอลลงใน cutty.devallegro.pl, github.com, news.ycombinator.com — แล้วคุณจะพบว่าไม่มีอะไรมาขัดขวางการทำงานของคุณเลย

สุดท้ายนี้, เรื่องส่วนตัวเล็กน้อย

ฉันเคยคิดมานานว่าผลิตภัณฑ์ชนะกันด้วยฟีเจอร์ที่ยิ่งใหญ่ ด้วยสิ่งที่ดูน่าตื่นตาตื่นใจเพียงอย่างเดียว ซึ่งสามารถนำไปแสดงบนสไลด์ได้และเป็นสิ่งที่ผู้คนจะเขียนถึง และใช่ บางครั้งมันก็เป็นเช่นนั้น

ยิ่งผมสร้าง cutty นานขึ้นเท่าไหร่ ผมก็ยิ่งรู้สึกแรงขึ้นเท่านั้นว่าความจงรักภักดีของผู้ใช้งานนั้นเกิดขึ้นจากที่อื่น — ในช่วงเวลาไม่กี่ไมโครวินาทีเหล่านั้นที่ไม่มีใครสังเกตเห็นอย่างตั้งใจ คุณจำไม่ได้ด้วยซ้ำว่าเครื่องมือเป็นคนเติม https:// ให้คุณเอง คุณจำได้เพียงความรู้สึกโดยรวมว่า "ใช้งานได้ดีนะ" หรือ "ไม่น่ารำคาญ" ความรู้สึกนี้ไม่ได้เกิดขึ้นมาจากความว่างเปล่า แต่มันประกอบขึ้นจากการตัดสินใจเล็กๆ เพียงไม่กี่บรรทัดนับสิบครั้ง ซึ่งหากมองแยกกันเป็นเรื่องๆ คงไม่มีใครกล้าปกป้องว่ามัน "คุ้มค่ากับเวลาที่เสียไป"

บางทีนี่อาจเป็นหัวใจสำคัญของงานฝีมือ ไม่ใช่การเคลื่อนไหวที่ยิ่งใหญ่เพียงครั้งเดียว แต่คือความมุ่งมั่นที่จะยืนหยัดอยู่ข้างผู้ใช้งานในทุกๆ ครั้งที่ต้องกรอกฟอร์ม — แม้ว่ามันจะเป็นเรื่องของเวลาเพียงแค่สองวินาทีอันน้อยนิดก็ตาม แล้วคุณล่ะ? มีอะไรในเครื่องมือที่คุณใช้ช่วงนี้ที่ทำให้คุณหงุดหงิดจนเล็กน้อยเกินกว่าจะยอมรับได้ไหม? เพราะโดยปกติแล้ว งานที่ดีที่สุดมักจะรอให้เราเข้าไปจัดการตรงจุดนั้นแหละ