Dán văn bản hay một đường link để mã hóa phần trăm ngay khi gõ — chọn kiểu component, URI đầy đủ, hay form tùy vào nơi bạn định dùng.
File không bao giờ rời khỏi thiết bị của bạn
Component mã hóa gần như mọi ký tự, dùng cho một giá trị riêng lẻ. URI đầy đủ giữ nguyên các ký tự đặc biệt như / và ?. Form còn đổi dấu cách thành +.
URL chỉ chấp nhận an toàn một bảng ký tự giới hạn. Bất cứ thứ gì khác — dấu cách, dấu & không
đóng vai trò phân cách, một chữ cái có dấu — đều phải viết lại thành dấu phần trăm cộng hai chữ số
hex, mỗi bộ ba ứng với một byte. Trang này làm việc mã hóa đó ngay trong trình duyệt, theo đúng
kiểu mà nơi nhận chuỗi kết quả đang cần.
Bảng ký tự an toàn, và phần còn lại
Mọi trình phân tích URL đều đồng ý một điều tuyệt đối: chữ cái, chữ số và bốn dấu - . _ ~ không
bao giờ cần mã hóa và không mang ý nghĩa đặc biệt nào — đó là nhóm unreserved. Bộ mã hóa của
JavaScript, thứ chạy phía sau trang này, còn giữ nguyên thêm năm dấu nữa, ! * ' ( ), một quy ước
sót lại từ chuẩn URI cũ mà phần lớn công cụ vẫn tôn trọng tới nay. Ngoài nhóm gộp đó, còn hai nhóm
khác — những ký tự URL đã dùng làm dấu phân cách (/ ? # : @ &= và vài dấu khác), và mọi thứ còn
lại, từ một dấu cách đơn giản tới cả một câu tiếng Việt có dấu. Mã hóa chính là chọn đụng vào nhóm
nào trong hai nhóm còn lại đó.
Ví dụ 1: một dấu cách, ba cách viết
hello world mã hóa thành hello%20world ở cả kiểu component lẫn URI đầy đủ — dấu cách không nằm
trong nhóm unreserved nên cả hai đều mã hóa giống nhau. Kiểu form lại ra hello+world, vì một form
HTML khi gửi đi luôn dùng dấu + cho dấu cách thay vì %20.
Ví dụ 2: dấu + thật vẫn là dấu + thật
Mã hóa a+b thì component và form đều ra a%2Bb — riêng URI đầy đủ trả về a+b y nguyên, vì +
không thuộc nhóm nó bảo vệ. Có lý do cho sự bất đối xứng đó: ở component và form, dấu + bị mã hóa
để không bao giờ bị đọc nhầm thành dấu cách; còn URI đầy đủ coi như bạn đã biết rõ dấu + trong
địa chỉ của mình nghĩa là gì nên để nguyên.
Mẹo:Đang dựng query string từng giá trị một? Hãy mã hóa từng giá trị bằng component hoặc form, đừng dùng URI đầy đủ cho một giá trị đơn lẻ — URI đầy đủ không mã hóa & hay =, nên một giá trị chứa dấu đó sẽ bị đọc nhầm thành tham số thứ hai khi ghép vào query string.
Ví dụ 3: văn bản có dấu, từng byte một
Tiếng Việt mã hóa kiểu component thành Ti%E1%BA%BFng%20Vi%E1%BB%87t — mỗi chữ có dấu trước tiên
đổi thành các byte UTF-8, rồi mỗi byte thành một bộ ba %XX riêng. Chỉ riêng chữ ế đã tốn ba byte
và ba bộ ba, %E1%BA%BF; một chữ cái ASCII thường như T thì không cần gì cả. Kiểu form cho kết
quả giống hệt, chỉ khác dấu cách đổi thành +: Ti%E1%BA%BFng+Vi%E1%BB%87t.
Component, URI đầy đủ, hay form
Kiểu
Mã hóa / ? # & =
Dấu cách thành
Dùng khi
Component
có
%20
Một giá trị riêng — từ khóa tìm kiếm, một đoạn path, đích chuyển hướng
URI đầy đủ
không
%20
Cả một địa chỉ bạn đang chuẩn hóa, không phải đang dựng mới
Form
có
+
Giá trị gửi vào form HTML hay query string của nó
Mẹo:Chưa chắc chọn kiểu nào? Component là lựa chọn an toàn mặc định cho bất cứ thứ gì nhỏ hơn cả một URL — chỉ dùng URI đầy đủ khi bạn đang chuẩn hóa một địa chỉ muốn giữ nguyên khả năng điều hướng, và chỉ dùng form khi đích đến thật sự là một form hoặc đọc query string theo kiểu đó.
Vì sao vẫn cần tới kiểu URI đầy đủ
Nếu component luôn an toàn cho một mảnh nhỏ, tưởng chừng nó nên là lựa chọn mặc định cho mọi
trường hợp. Nhưng đem cả một địa chỉ hoàn chỉnh qua component, mọi dấu / và ? cũng bị mã hóa
cùng với dấu cách, biến https://example.com/a b thành chuỗi phần trăm vô dụng thay vì một link
vẫn điều hướng được với đúng một dấu cách được mã hóa. URI đầy đủ sinh ra chính cho trường hợp đó —
chuẩn hóa một địa chỉ gõ tay mà không phá cấu trúc khiến nó còn là một địa chỉ.
Câu hỏi thường gặp
Mã hóa URL kiểu component, URI đầy đủ và form khác nhau ở đâu?
Component mã hóa gần như mọi ký tự không phải chữ, số hay bốn dấu - . _ ~, nên dùng an toàn cho một giá trị đơn lẻ sẽ được ghép vào URL lớn hơn — một từ khóa tìm kiếm, một tham số. URI đầy đủ nhẹ tay hơn: nó giữ nguyên những ký tự làm nên cấu trúc URL như / ? # : @ & =, vì nó giả định bạn đang mã hóa cả một địa chỉ chứ không phải một mảnh của nó. Form giống hệt component, chỉ khác một chỗ — dấu cách thành +, đúng cách trình duyệt gửi một form HTML.
Vì sao form lại đổi dấu cách thành dấu + thay vì %20?
Vì đó là định dạng thật sự của application/x-www-form-urlencoded — kiểu mã hóa một form HTML dùng khi gửi bằng method="get" hay body của POST thường. Quy ước này có từ trước cả cách mã hóa %20 cho dấu cách, và mọi framework phía server vẫn hiểu dấu + là dấu cách trong ngữ cảnh đó.
Vì sao mã hóa chuỗi "a+b" lại ra "a%2Bb" chứ không giữ nguyên dấu +?
Dấu + trong chuỗi bạn gõ là dữ liệu thật, không phải một cách viết tắt của dấu cách — bạn gõ nó vì muốn đúng ký tự +. Mã hóa luôn đổi nó thành %2B để khi giải mã lại, ai đọc cũng ra đúng dấu +, không lẫn với dấu cách. Chiều ngược lại — dấu cách thành + — chỉ chạy một chiều và chỉ ở chế độ form, nên dấu + thật không bao giờ bị hiểu nhầm.
Công cụ này giữ nguyên những ký tự nào, không đổi?
Chữ cái, chữ số, và bốn dấu - . _ ~ — nhóm ký tự luôn được mọi trình phân tích URL hiểu giống nhau, không cần mã hóa. Bộ mã hóa của JavaScript, thứ chạy phía sau trang này, còn giữ nguyên thêm năm dấu nữa — ! * ' ( ) — một quy ước còn sót lại từ chuẩn cũ. Mọi thứ khác — dấu câu còn lại, và mọi ký tự ngoài bảng ASCII — sẽ thành bộ ba %XX ở cả hai chế độ component lẫn form; riêng dấu cách là ngoại lệ, thành %20 ở component nhưng thành + ở form.
Mã hóa có bao giờ báo lỗi không?
Trang này không báo lỗi trong trường hợp thường gặp. Trường hợp hiếm là một surrogate UTF-16 lẻ đôi — nửa cặp ký tự không có phần còn lại, thường không xảy ra khi gõ tay nhưng có thể xuất hiện từ một lần copy-paste bị lỗi. Vì nửa ký tự đó không có cách mã hóa hợp lệ, nó được thay bằng ký tự thay thế Unicode chuẩn thay vì làm hỏng cả chuỗi.
Văn bản tôi gõ vào đây có bị gửi lên đâu không?
Không. Việc mã hóa chạy bằng JavaScript ngay trong tab trình duyệt của bạn, ngay khi bạn gõ, và không có request nào mang văn bản rời khỏi máy. Mở tab Network của trình duyệt trong lúc dùng trang này sẽ không thấy gì liên quan tới nội dung — hữu ích khi thứ bạn mã hóa là một token, một link nội bộ, hay bất cứ gì bạn không muốn gửi lên server chỉ để đổi định dạng.
Khi nào nên chọn URI đầy đủ thay vì component?
Khi bạn đã có sẵn một địa chỉ hoàn chỉnh và chỉ muốn mã hóa phần không an toàn — dấu cách trong path, hay ký tự có dấu trong domain hoặc path — trong khi vẫn giữ nguyên / ? # và = làm nên hình dạng của địa chỉ đó. Đem một giá trị đơn lẻ đi mã hóa kiểu URI đầy đủ thì dấu & hay = bên trong nó sẽ không được mã hóa, dễ bị đọc nhầm thành dấu phân cách và làm hỏng query string bạn đang dựng.