URL Encoding และ Query Strings: คู่มือปฏิบัติ
ทำความเข้าใจ percent-encoding, reserved characters และวิธีสร้าง URL ที่ปลอดภัยสำหรับ API และการแชร์ลิงก์ โดยไม่มีลิงก์เสียหาย
URL อนุญาตให้ใช้อักขระได้เพียงจำนวนจำกัดในส่วน path และ query อักขระอื่นๆ ทั้งหมดต้องผ่าน percent-encoding (เช่น ช่องว่าง → %20, & → %26) หากทำผิดพลาดจะนำไปสู่ 404, แท็ก analytics เสียหาย และบั๊กแอบแฝงใน API
อะไรบ้างที่ต้องเข้ารหัส?
- ค่าใน query ที่มีช่องว่าง,
&,=,#หรือข้อความที่ไม่ใช่ ASCII (อีโมจิ, อักขระเน้นเสียง) จะต้องถูก encode - Path segment ที่มี slash หรืออักขระพิเศษก็ต้องการการ encode เช่นกัน มิฉะนั้น router จะอ่านขอบเขตของแต่ละ segment ผิดพลาด
เบราว์เซอร์มักแสดง URL ที่ "อ่านง่าย" บน address bar แต่จะส่งข้อมูลในรูปแบบที่ encode แล้วจริงๆ อย่างไรก็ตาม API คาดหวังให้คุณ encode อย่างชัดเจนเมื่อสร้าง string ด้วยตนเอง
encodeURIComponent vs encodeURI
ใน JavaScript:
encodeURIComponent— ใช้สำหรับ ค่าของ query parameter (และโดยปกติรวมถึง key ด้วย) โดยจะ encode แทบทุกอย่างที่อาจทำให้ URL เสียหายencodeURI— ใช้สำหรับ URL ทั้งหมด เฉพาะเมื่อต้องการรักษา delimiter อย่าง?และ#ไว้ ไม่ค่อยได้ใช้ในงาน API ประจำวัน
const q = "hello world & friends";
const params = new URLSearchParams({ q });
console.log(params.toString()); // q=hello+world+%26+friends
URLSearchParams จัดการการ encode สำหรับ query แบบ application/x-www-form-urlencoded มาตรฐาน และเป็นทางเลือกที่ดีกว่าการต่อ string ด้วยตนเอง
การสร้าง URL ที่มีหลาย parameter
เมื่อคุณเพิ่ม UTM tags, ตัวกรอง หรือ API key ข้อผิดพลาดมักสะสม ไม่ว่าจะเป็น ? ซ้ำกัน, & ที่ไม่ได้ encode หรือลำดับที่คลุมเครือ การใช้ helper เล็กๆ หรือ visual builder ช่วยให้ string สุดท้ายถูกต้องเสมอ
ลองใช้เครื่องมือ URL Encode / Decode ของเราเพื่อตรวจสอบว่า string เปลี่ยนแปลงอย่างไร และ URL & Query String Builder เพื่อประกอบลิงก์แบบเต็มด้วยการ encode ที่รองรับ UTF-8
cURL และ fetch
เมื่อคัดลอก request จาก browser devtools ให้ระวัง query string ที่ ถูก encode ไปแล้ว การนำไปวางในโค้ดอาจทำให้เกิด double-encode ค่าต่างๆ ตัวแปลง cURL to fetch() ของเราช่วยแปลง cURL ที่ใช้งานได้เป็น JavaScript ขณะที่คุณตรวจสอบ URL แยกต่างหาก
หากลิงก์ "ใช้งานได้ใน Chrome" แต่ล้มเหลวในสคริปต์ของคุณ ให้เปรียบเทียบ raw query string ทีละ byte
Checklist เบื้องต้น
- Encode ค่า ก่อนนำมาต่อใน
?a=...&b=... - ควรใช้
URL+URLSearchParamsแทนการสร้าง string ด้วยตนเอง - สำหรับ internationalized domain names (IDN) เบราว์เซอร์จะจัดการ punycode ใน hostname ให้ — ให้โฟกัสการ encode ที่ path และ query เท่านั้น