Chuỗi mã hóa phần trăm ẩn ở ba nơi: cả một URL, một giá trị riêng lẻ, và một query string ghép từ
nhiều giá trị. Trang này đọc ngược cả ba, từng byte một, và tách query thành các cặp key/value để
bạn không phải tự dò từng dấu &.
Đọc một escape bằng tay
Một bộ ba phần trăm là một byte viết dưới dạng hex: %20 là byte 0x20, dấu cách. %2B là 0x2B,
dấu cộng thật. Ký tự nhiều byte cần nhiều bộ ba hơn — %E1%BA%BF là ba byte ghép thành một ký tự
UTF-8, chữ ế. Đặt cạnh chữ ASCII, Ti%E1%BA%BFng%20Vi%E1%BB%87t giải mã ra Tiếng Việt: chữ
ASCII đi qua nguyên vẹn, mỗi chữ có dấu tốn ba bộ ba, %20 thành dấu cách giữa hai từ.
Chọn chế độ Component, Full URI hay Form
Ba chế độ giải mã một lượng ký tự khác nhau, chọn sai chế độ thì hoặc escape bị bỏ sót, hoặc cấu
trúc vốn không nên đụng vào lại bị phá. Component giải mã mọi ký tự đã mã hóa mà nó nhận ra, phù
hợp cho một giá trị đơn lẻ đứng riêng — một tham số query, một đoạn path, một cookie. Full URI
dành cho cả một địa chỉ dán nguyên khối: nó cố tình giữ nguyên dạng đã mã hóa của / ? # & = + $ , : ; @, để một dấu / từng bị mã hóa hợp lệ bên trong tên file (%2F) không bị giải mã ngược thành
dấu / thật rồi bị đọc nhầm thành một đoạn path mới. Form hoạt động như Component nhưng đọc
thêm dấu + thành dấu cách, đúng cách một trình duyệt mã hóa dữ liệu form HTML khi gửi đi — dùng
chế độ này cho bất cứ thứ gì đến từ một body application/x-www-form-urlencoded hay một query
string, vì dấu + thật không còn cách nào khác để sống sót qua vòng mã hóa đó.
Hai kiểu lỗi khi giải mã
100% lỗi ngay ký tự cuối — không có gì theo sau dấu % để đọc thành chữ số hex thứ hai. 50%2 off lỗi sớm hơn một ký tự, ngay tại dấu %, vì %2 tiếp theo là dấu cách chứ không phải chữ số
hex. Cả hai báo là chuỗi percent-encode không hợp lệ, kèm đúng vị trí dấu % gây lỗi.
Kiểu lỗi thứ hai xảy ra khi escape đúng cú pháp nhưng byte tạo ra không ghép thành văn bản hợp lệ.
%E1 một mình mở đầu một ký tự UTF-8 ba byte mà không có byte tiếp theo — không có văn bản nào để
tạo ra. %FF%FE cùng kiểu. Cả hai báo không phải UTF-8 hợp lệ: byte chưa từng là văn bản, không
phải bạn gõ sai.
Tách một query string
Dán https://example.com/search?q=hello+world&lang=vi#frag vào, bảng bên dưới hiện hai dòng: q
→ hello world, lang → vi. Path trước dấu ? và #frag sau đó đều bị bỏ qua — cả hai không
thuộc query — còn dấu + trong hello+world giải mã ra dấu cách, theo quy ước form.
Một query string cũng có nhiều cách viết khác nhau mà vẫn hợp lệ: dấu cách có thể viết là + hay
%20, còn dấu . giải mã ra giống hệt nhau dù có bị mã hóa thành %2E hay không — nên viết lại
một chuỗi từ các mảnh đã giải mã có thể trông khác chuỗi bạn từng dán, dù mang đúng ý nghĩa.