Mã hóa và giải mã URL, giải thích dành cho lập trình viên
Hãy gõ một khoảng trắng vào URL, hoặc một từ tiếng Việt, hoặc một dấu và (&) thuộc về dữ liệu của bạn chứ không phải cấu trúc địa chỉ, và một thứ gì đó phải nhường bước. Web chỉ đảm bảo truyền tải an toàn cho một tập hợp nhỏ, có thể đoán trước của các ký tự ASCII. Mọi thứ khác phải được bọc trong định dạng mà router, server và trình duyệt đều đồng ý. Định dạng đó là percent-encoding, thường gọi là mã hóa URL, và trang này cho phép bạn chuyển đổi văn bản theo cả hai chiều trực tiếp trong trình duyệt.

Percent-encoding thực chất là gì
Quy tắc hoàn toàn có tính máy móc và dễ theo dõi. Bất kỳ ký tự nào không thể xuất hiện trực tiếp đều được thay thế bằng ký hiệu % theo sau là hai chữ số thập lục phân biểu diễn giá trị byte của ký tự đó. Khoảng trắng thành %20. Dấu cộng thành %2B. Dấu thăng thành %23. Khi một ký tự ánh xạ thành nhiều byte, như hầu hết văn bản không phải ASCII dưới UTF-8, bạn sẽ nhận được nhiều bộ ba liên tiếp: ký hiệu euro trở thành %E2%82%AC. Giải mã đảo ngược quá trình, đọc lại mỗi bộ ba thành byte gốc của nó.
Quy ước này được định nghĩa trong đặc tả URI (RFC 3986) và cố tình nhàm chán. Nhàm chán mới là điểm mấu chốt. Mỗi HTTP client và server hoạt động đúng đắn trên hành tinh này đều tuân theo cùng quy tắc, vì vậy một liên kết được mã hóa đúng ở một nơi sẽ đến đích nguyên vẹn ở mọi nơi khác.
Tại sao nó phải tồn tại
URL mang hai loại ký tự với vai trò rất khác nhau. Ký tự dành riêng như /, ?, #, &, = và : có tính cấu trúc. Chúng cho parser biết đường dẫn kết thúc ở đâu và chuỗi truy vấn bắt đầu ở đâu, hoặc nơi một tham số dừng lại và tham số tiếp theo bắt đầu. Nếu dữ liệu thực tế của bạn chứa một trong những ký hiệu đó, nó phải được mã hóa để parser không nhầm nó với dấu câu. Một mã tham chiếu đơn hàng như A&B/2024 đặt thô vào chuỗi truy vấn sẽ bị đọc nhầm thành hai tham số và một đoạn đường dẫn.
Sau đó có các ký tự không an toàn và không phải ASCII: khoảng trắng, dấu ngoặc kép, dấu ngoặc nhọn, chữ có dấu, emoji, bất cứ thứ gì ngoài phạm vi ASCII thuần túy. Những thứ này không có lý do gì để xuất hiện trực tiếp trong URL, hoặc vì chúng bị biến dạng trong quá trình truyền tải hoặc vì không có biểu diễn xác định. Mã hóa chúng giữ các liên kết gọn gàng và có thể đoán trước thay vì để kết quả tùy cơ.
Nơi nó xuất hiện trong công việc thực tế
Chuỗi truy vấn là trường hợp điển hình. Mọi giá trị bạn gắn vào ?key=... nên được mã hóa để đầu vào người dùng không thể phá vỡ cấu trúc. Điều tương tự áp dụng cho việc gửi form HTML dưới dạng application/x-www-form-urlencoded, nơi trình duyệt tự động mã hóa các giá trị trường (và theo quy ước lịch sử, chuyển khoảng trắng thành + thay vì %20). Bạn cũng sẽ gặp nó khi tạo liên kết trỏ đến các trang có tiêu đề không phải Latin, khi xây dựng thủ công các yêu cầu API, khi truyền mục tiêu chuyển hướng dưới dạng tham số, và khi debug tại sao một yêu cầu trông ổn trong thanh địa chỉ lại đến server bị méo mó.

encodeURI và encodeURIComponent
JavaScript cung cấp hai bộ mã hóa, và chọn sai cái là một lỗi phổ biến. Sự khác biệt là về phạm vi. encodeURIComponent dành cho một mảnh dữ liệu đơn lẻ, chẳng hạn một giá trị truy vấn. Nó mã hóa hầu hết mọi thứ, bao gồm các ký tự dành riêng /, ?, :, @, &, =, + và #. Đó chính xác là điều bạn muốn khi dữ liệu được phép chứa những ký hiệu đó như văn bản thông thường.
encodeURI dành cho toàn bộ địa chỉ mà bạn muốn vẫn hoạt động. Nó giữ nguyên các ký tự cấu trúc, vì vậy các dấu gạch chéo, dấu hai chấm và dấu chấm hỏi giữ URL lại vẫn tồn tại. Hãy dùng nó khi bạn có một URL đầy đủ và chỉ muốn làm sạch khoảng trắng hoặc các ký tự không phải ASCII; hãy dùng encodeURIComponent bất cứ khi nào bạn chèn một giá trị vào URL lớn hơn. Quy tắc đơn giản: mã hóa toàn bộ liên kết bằng encodeURI, mã hóa các phần bạn nhồi vào bằng encodeURIComponent.
Mọi thứ ở lại trên máy của bạn
Công cụ này chạy hoàn toàn trong trình duyệt của bạn. Văn bản bạn dán vào được mã hóa hoặc giải mã cục bộ bằng các thủ tục tiêu chuẩn và không bao giờ truyền đến server, điều này khiến nó an toàn cho token, tham số đã ký hoặc bất cứ thứ gì khác mà bạn không muốn gửi qua mạng. Nếu bạn làm việc với các chuyển đổi văn bản khác, bộ chuyển đổi Base64 nằm ngay bên cạnh, và bạn có thể duyệt toàn bộ tập hợp công cụ dành cho lập trình viên để có thêm các tiện ích hàng ngày.
Câu hỏi thường gặp
%20 trong URL có nghĩa là gì?
Đó là khoảng trắng được mã hóa. Ký tự khoảng trắng không được phép xuất hiện trực tiếp trong URL, vì vậy nó được thay thế bằng ký hiệu phần trăm và giá trị thập lục phân 20, là giá trị byte của khoảng trắng.
Tại sao đôi khi tôi thấy dấu cộng thay vì %20?
Dữ liệu form HTML kiểu application/x-www-form-urlencoded mã hóa khoảng trắng dưới dạng dấu cộng theo quy ước lịch sử. Trong đường dẫn hoặc truy vấn thông thường, khoảng trắng được mã hóa là %20. Cả hai đều giải mã trở lại thành khoảng trắng trong ngữ cảnh thích hợp của chúng.
Khi nào nên dùng encodeURIComponent thay vì encodeURI?
Dùng encodeURIComponent cho một giá trị đơn lẻ bạn đang chèn vào URL, chẳng hạn tham số truy vấn, vì nó mã hóa cả ký tự dành riêng. Dùng encodeURI cho một địa chỉ đầy đủ khi bạn muốn bảo tồn các dấu gạch chéo, dấu hai chấm và dấu chấm hỏi giữ nó lại với nhau.
Mã hóa URL có thay đổi ý nghĩa dữ liệu của tôi không?
Không. Mã hóa hoàn toàn có thể đảo ngược. Giải mã kết quả cho lại chính xác văn bản gốc, byte cho byte, miễn là cùng bộ ký tự được sử dụng ở cả hai đầu.
Các ký tự không phải ASCII như chữ có dấu hoặc emoji được xử lý thế nào?
Chúng trước tiên được chuyển thành các byte UTF-8, sau đó mỗi byte trở thành bộ ba phần trăm riêng của nó. Một chữ có dấu hoặc emoji đơn lẻ vì vậy có thể mở rộng thành nhiều bộ ba trong đầu ra được mã hóa.
Văn bản của tôi có được gửi đến server khi dùng công cụ này không?
Không. Mã hóa và giải mã diễn ra hoàn toàn trong trình duyệt của bạn. Không có gì bạn dán vào được tải lên, vì vậy an toàn khi dùng với chuỗi riêng tư hoặc nhạy cảm.
