URL Encoding คืออะไร? คู่มือ Percent-Encoding ฉบับครบถ้วน
ทุกครั้งที่ค้นหา คลิกลิงก์ที่มีอักขระพิเศษ หรือส่งฟอร์มบนเว็บ URL encoding ทำงานอยู่เบื้องหลังเพื่อแปลงอักขระที่ไม่ปลอดภัยให้อยู่ในรูปแบบที่ส่งผ่านอินเทอร์เน็ตได้อย่างถูกต้อง
สารบัญ
- URL คืออะไร?
- ส่วนประกอบของ URL
- URL Encoding คืออะไร?
- ทำไมต้องใช้ URL Encoding?
- URL Encoding ทำงานอย่างไร
- Reserved และ Unreserved Characters
- อักขระ URL-Encoded ที่พบบ่อย
- การ Encode Unicode และอักขระนานาชาติ
- URL Encoding ในภาษาโปรแกรม
- encodeURI เทียบกับ encodeURIComponent
- ข้อผิดพลาดที่พบบ่อยกับ URL Encoding
- ตัวอย่างการใช้งานจริง
URL คืออะไร?
URL หรือ Uniform Resource Locator คือที่อยู่ของ resource บนอินเทอร์เน็ต ไม่ว่าจะเป็นหน้าเว็บ รูปภาพ API endpoint ไฟล์ หรือรายการดาวน์โหลด
URL บอกเบราว์เซอร์ว่า resource อยู่ที่ไหน ต้องใช้ protocol ใด และมีข้อมูลเพิ่มเติมอย่าง query parameters หรือ fragment อะไรบ้าง
ตัวอย่างเช่น https://www.example.com/search?q=hello+world มีทั้ง scheme, host, path และ query string
ส่วนประกอบของ URL
URL แบบเต็มสามารถประกอบด้วยหลายส่วน:
https://user:pass@www.example.com:443/path/page?key=value&q=test#section
scheme userinfo host port path query fragment| ส่วนประกอบ | ตัวอย่าง | คำอธิบาย |
|---|---|---|
| Scheme | https | Protocol ที่ใช้เข้าถึง resource |
| User info | user:pass | ข้อมูล credential แบบ optional ซึ่งปัจจุบันแทบไม่ใช้แล้ว |
| Host | www.example.com | ชื่อโดเมนหรือ IP address ของ server |
| Port | 443 | port ของ server ซึ่งมักถูกกำหนดโดยอัตโนมัติสำหรับ HTTP/HTTPS |
| Path | /path/page | ตำแหน่ง resource บน server |
| Query | key=value&q=test | ข้อมูล key-value หลังเครื่องหมาย question mark |
| Fragment | #section | ตำแหน่งภายในหน้าเว็บที่ไม่ถูกส่งไป server |
URL Encoding คืออะไร?
URL encoding หรือ percent-encoding คือการแปลงอักขระที่ไม่ปลอดภัยหรือไม่อนุญาตใน URL ให้อยู่ในรูปแบบที่ใช้ใน URL ได้
รูปแบบคือเครื่องหมาย percent ตามด้วยเลขฐานสิบหก 2 หลัก เช่น ช่องว่างกลายเป็น %20 เพราะ byte ของช่องว่างคือ decimal 32 หรือ hex 20
Percent-encoding ถูกกำหนดในมาตรฐาน URI เช่น RFC 3986 และเป็นพื้นฐานสำคัญที่ทำให้ URL ส่งข้อความได้อย่างปลอดภัย
Before encoding:
https://example.com/search?q=hello world&lang=en
After encoding:
https://example.com/search?q=hello%20world&lang=en
Space becomes %20ทำไมต้องใช้ URL Encoding?
URL encoding จำเป็นด้วยเหตุผลหลายข้อ:
- Reserved characters มีความหมายพิเศษ - เช่น
?,&,=และ#ใช้แบ่งส่วนของ URL - ช่องว่างใส่ตรง ๆ ไม่ได้ - ต้อง encode เป็น
%20หรือบางกรณีเป็น+ใน form data - ข้อความนอก ASCII ต้องแปลงเป็น bytes - ภาษาไทย ญี่ปุ่น ตัวอักษรมี accent และอีโมจิต้องแปลงเป็น UTF-8 ก่อน
- รักษาความถูกต้องของข้อมูล - encoding ป้องกันไม่ให้ browser, proxy หรือ server ตีความข้อมูลผู้ใช้เป็นโครงสร้าง URL
- เกี่ยวข้องกับความปลอดภัย - การ encode ที่ถูกบริบทช่วยลดปัญหา parameter injection และ redirect ที่พัง
URL Encoding ทำงานอย่างไร
กระบวนการทำงานมีขั้นตอนง่าย ๆ:
- นำอักขระที่ต้อง encode มา
- แปลงอักขระนั้นเป็น UTF-8 bytes
- เขียนแต่ละ byte เป็น % ตามด้วยเลขฐานสิบหก 2 หลัก
สำหรับอักขระ ASCII แต่ละอักขระมี 1 byte:
Character: space ASCII: 32 Hex: 20 Encoded: %20
Character: ! ASCII: 33 Hex: 21 Encoded: %21
Character: # ASCII: 35 Hex: 23 Encoded: %23
Character: @ ASCII: 64 Hex: 40 Encoded: %40สำหรับอักขระนอก ASCII, UTF-8 อาจมีหลาย bytes:
Character: é UTF-8 bytes: C3 A9 Encoded: %C3%A9
Character: ñ UTF-8 bytes: C3 B1 Encoded: %C3%B1
Character: 日 UTF-8 bytes: E6 97 A5 Encoded: %E6%97%A5
Character: 😀 UTF-8 bytes: F0 9F 98 80 Encoded: %F0%9F%98%80Reserved และ Unreserved Characters
RFC 3986 แบ่งอักขระใน URL เป็นกลุ่ม reserved และ unreserved
Unreserved characters
ตัวอักษร ตัวเลข hyphen underscore period และ tilde ปลอดภัยและโดยทั่วไปไม่ต้อง encode: A-Z a-z 0-9 - _ . ~
Reserved characters
อักขระเช่น : / ? # [ ] @ ! $ & ' ( ) * + , ; = อาจมีความหมายในโครงสร้าง URL ควร encode เมื่อเป็นข้อมูล ไม่ใช่ syntax
Unsafe หรือ special characters
ช่องว่าง เครื่องหมาย percent quotes angle brackets อักขระนอก ASCII และ control characters ควรถูก encode
อักขระ URL-Encoded ที่พบบ่อย
| อักขระ | Encoded | อักขระ | Encoded |
|---|---|---|---|
space | %20 | ! | %21 |
" | %22 | # | %23 |
$ | %24 | % | %25 |
& | %26 | ' | %27 |
( | %28 | ) | %29 |
+ | %2B | , | %2C |
/ | %2F | : | %3A |
? | %3F | = | %3D |
การ Encode Unicode และอักขระนานาชาติ
URL สมัยใหม่มักมีข้อความหลายภาษา อักขระจะถูกแปลงเป็น UTF-8 ก่อน แล้ว encode แต่ละ byte ด้วย percent-encoding
Example: Encoding "café" in a URL
c -> c (ASCII, no encoding needed)
a -> a (ASCII, no encoding needed)
f -> f (ASCII, no encoding needed)
é -> UTF-8 C3 A9 -> %C3%A9
Result: caf%C3%A9
Full URL: https://example.com/search?q=caf%C3%A9เบราว์เซอร์มักแสดงอักขระที่อ่านง่ายใน address bar แต่ส่งรูปแบบที่ encode แล้วใน request จริง
URL Encoding ในภาษาโปรแกรม
ภาษาโปรแกรมส่วนใหญ่มี helper สำหรับ URL encoding และ decoding:
JavaScript
// Encode a single query parameter value
encodeURIComponent("hello world & goodbye")
// "hello%20world%20%26%20goodbye"
// Decode it back
decodeURIComponent("hello%20world%20%26%20goodbye")
// "hello world & goodbye"
// Encode an entire URI while keeping URL structure intact
encodeURI("https://example.com/path?q=hello world")
// "https://example.com/path?q=hello%20world"
// URLSearchParams handles query encoding automatically
const params = new URLSearchParams({ q: "hello world", lang: "en" });
params.toString();
// "q=hello+world&lang=en"Python
from urllib.parse import quote, unquote, urlencode
quote("hello world & goodbye")
# 'hello%20world%20%26%20goodbye'
unquote("hello%20world%20%26%20goodbye")
# 'hello world & goodbye'
urlencode({"q": "hello world", "lang": "en"})
# 'q=hello+world&lang=en'
quote("/path/to/resource", safe="/")
# '/path/to/resource'PHP
// Spaces become %20
rawurlencode("hello world & goodbye");
// "hello%20world%20%26%20goodbye"
// Spaces become + for form-style data
urlencode("hello world & goodbye");
// "hello+world+%26+goodbye"
rawurldecode("hello%20world"); // "hello world"
urldecode("hello+world"); // "hello world"Java
import java.net.URLEncoder;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
URLEncoder.encode("hello world", StandardCharsets.UTF_8);
// "hello+world"
URLDecoder.decode("hello%20world", StandardCharsets.UTF_8);
// "hello world"encodeURI เทียบกับ encodeURIComponent
JavaScript มีฟังก์ชันสองตัวที่ชื่อคล้ายกันมาก แต่ใช้คนละงาน:
| ฟังก์ชัน | ใช้เมื่อ | ไม่ encode |
|---|---|---|
encodeURI() | encode URL ทั้งเส้นโดยคงโครงสร้าง URL ไว้ | : / ? # [ ] @ ! $ & ' ( ) * + , ; = |
encodeURIComponent() | encode ค่าพารามิเตอร์หรือ path segment ทีละส่วน | - _ . ~ ! ' ( ) * |
const value = "price=10¤cy=USD";
// Wrong for parameter values: & and = are not encoded
encodeURI("https://api.com/search?filter=" + value);
// "https://api.com/search?filter=price=10¤cy=USD"
// Server sees two parameters: filter=price=10 and currency=USD
// Correct: encode the value as one component
"https://api.com/search?filter=" + encodeURIComponent(value);
// "https://api.com/search?filter=price%3D10%26currency%3DUSD"
// Server sees one parameter: filter=price=10¤cy=USDหลักจำง่าย
ใช้ encodeURIComponent() กับค่าทีละส่วน เช่น query parameters และ path segments ใช้ encodeURI() เฉพาะกับ URL ที่ประกอบเสร็จแล้วทั้งเส้น
ข้อผิดพลาดที่พบบ่อยกับ URL Encoding
1. Double encoding
การ encode ข้อความที่ encode แล้วจะเปลี่ยน %20 เป็น %2520 เพราะเครื่องหมาย percent ถูก encode เป็น %25 ควร encode เพียงครั้งเดียว ณ จุดที่นำข้อมูลเข้า URL
2. ใช้ encodeURI กับค่า query
encodeURI ไม่ encode & หรือ = ทำให้ input ของผู้ใช้อาจกลายเป็น query parameter เพิ่มโดยไม่ตั้งใจ ควรใช้ encodeURIComponent กับค่า
3. สับสนระหว่าง + กับ %20
+ หมายถึงช่องว่างใน application/x-www-form-urlencoded แต่ decodeURIComponent ไม่แปลง + เป็นช่องว่างให้อัตโนมัติ
4. ไม่ encode ชื่อไฟล์หรือ path segment
ชื่อไฟล์อาจมีช่องว่างและอักขระพิเศษ ควร encode แต่ละ path segment ก่อนใส่ใน URL
const encoded = encodeURIComponent("hello world");
// "hello%20world"
encodeURIComponent(encoded);
// "hello%2520world" <-- wrong, % became %25
const value = "hello world";
const url = "/search?q=" + encodeURIComponent(value);
// Encode once at the boundary// Broken or ambiguous URL
const url = "/files/" + "my report (final).pdf";
// "/files/my report (final).pdf"
// Properly encoded path segment
const url = "/files/" + encodeURIComponent("my report (final).pdf");
// "/files/my%20report%20(final).pdf"ตัวอย่างการใช้งานจริง
URL encoding พบได้ตลอดในการทำเว็บจริง:
Google Search
https://www.google.com/search?q=what+is+URL+encoding%3F
Spaces become +
Question mark becomes %3FAPI Requests
GET /api/users?name=O%27Brien&city=San%20Francisco
Decoded:
name = O'Brien
city = San FranciscoEmail Mailto Links
mailto:user@example.com?subject=Hello%20World&body=Hi%2C%20how%20are%20you%3F
Decoded:
subject = Hello World
body = Hi, how are you?Redirect URLs
https://auth.example.com/login?redirect=https%3A%2F%2Fapp.example.com%2Fdashboard%3Ftab%3Dsettings
Decoded redirect value:
https://app.example.com/dashboard?tab=settingsEncode และ Decode URL ได้ทันที
ใช้เครื่องมือ URL Encoder & Decoder ฟรีของเราเพื่อ encode หรือ decode URL, query parameter หรือข้อความใด ๆ ได้ทันทีในเบราว์เซอร์
ลองใช้ URL Encoder & Decoderแหล่งอ้างอิง
- Berners-Lee, T., Fielding, R., & Masinter, L. (2005). RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax. https://datatracker.ietf.org/doc/html/rfc3986
- Berners-Lee, T., Masinter, L., & McCahill, M. (1994). RFC 1738 - Uniform Resource Locators (URL). https://datatracker.ietf.org/doc/html/rfc1738
- Mozilla Developer Network. encodeURIComponent() - JavaScript. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
- WHATWG. URL Standard. https://url.spec.whatwg.org/
- Python Software Foundation. urllib.parse - Parse URLs into components. https://docs.python.org/3/library/urllib.parse.html