Bộ mã hóa/giải mã URL miễn phí

Mã hóa hoặc giải mã URL và các thành phần URI ngay lập tức.

Không có dữ liệu nào rời khỏi thiết bị của bạn

Về mã hóa URL

Mã hóa URL (còn gọi là mã hóa phần trăm) chuyển đổi các ký tự không được phép trong URL sang định dạng có thể truyền an toàn. Các ký tự đặc biệt được thay thế bằng dấu phần trăm (%) theo sau là hai chữ số thập lục phân biểu thị giá trị byte của ký tự đó.

Lược sử ngắn về quy tắc mã hóa

Quy ước mã hóa phần trăm có nguồn gốc từ RFC 1738 ("Uniform Resource Locators (URL)", Tim Berners-Lee, Larry Masinter và Mark McCahill, tháng 12 năm 1994), đặc tả URL chính thức đầu tiên do IETF công bố. RFC 1738 định nghĩa bộ ký tự "reserved" gốc (các ký tự có ý nghĩa cấu trúc trong URL và phải được mã hóa khi đứng làm dữ liệu) và bộ "unreserved" gốc (các ký tự không bao giờ cần mã hóa). Đặc tả được sửa đáng kể trong RFC 2396 (Berners-Lee, Fielding, Masinter, tháng 8 năm 1998) rồi sau đó, một cách dứt khoát, trong RFC 3986 ("Uniform Resource Identifier (URI): Generic Syntax", Berners-Lee, Fielding, Masinter, tháng 1 năm 2005), văn bản hiện vẫn là đặc tả URI chính thức. RFC 3986 mở rộng bộ unreserved bao gồm ký tự ngã (~), chính thức hóa UTF-8 làm bộ mã hóa cho ký tự không-ASCII trong IRI, và siết chặt quy tắc về khi nào ký tự reserved phải được mã hóa phần trăm hay để nguyên. Cho URI không-ASCII, RFC 3987 ("Internationalized Resource Identifiers", Duerst và Suignard, tháng 1 năm 2005) định nghĩa phần mở rộng IRI cho phép URL chứa ký tự Unicode gốc, ánh xạ dạng IRI sang dạng URI tiêu chuẩn qua UTF-8 + mã hóa phần trăm. Riêng cho tên miền, RFC 3492 định nghĩa Punycode (Costello, tháng 3 năm 2003), bộ mã hóa dùng để biểu diễn nhãn miền Unicode (xn--exmpla-...) trong DNS, tương tự về mặt cấu trúc nhưng dựa trên thuật toán khác. Đặc tả URL trên thực tế của web hiện đại là WHATWG URL Living Standard, do Anne van Kesteren biên tập, văn bản này mã hóa hành vi thực của trình duyệt, đôi khi tách khỏi RFC 3986 để duy trì tương thích ngược với cách URL hoạt động trên thực tế.

Reserved, unreserved, và những ký tự luôn bị mã hóa

Khoảng trắng trở thành %20, dấu và trở thành %26, dấu bằng trở thành %3D, và các ký tự không phải ASCII như chữ cái có dấu hoặc emoji được mã hóa thành chuỗi byte UTF-8 của chúng. Chữ cái, chữ số và các ký tự - _ . ~ không bao giờ được mã hóa (ký tự không dành riêng).

encodeURI và encodeURIComponent, khi nào dùng cái nào

JavaScript cung cấp hai bộ mã hóa tích hợp, cả hai đã được chuẩn hóa trong ECMAScript từ năm 1999 (ES3). Việc chọn giữa hai chính là quyết định mã hóa URL phổ biến nhất trong mã web, và chọn sai sẽ tạo ra các lỗi tinh vi vượt qua các bài kiểm thử trên đầu vào đơn giản nhưng vỡ trên dữ liệu người dùng thật chứa dấu &, # hoặc /.

Quy tắc nhớ: encodeURIComponent cho dữ liệu, encodeURI cho URL. Dùng nhầm thì hoặc bạn phá cấu trúc URL (encodeURIComponent trên cả một URL sẽ thoát các dấu / và & mà bạn cần), hoặc bạn phá việc thoát đầu vào người dùng (encodeURI trên giá trị query để dấu & lọt qua và dữ liệu của bạn sẽ bị parse thành nhiều tham số).

application/x-www-form-urlencoded, bộ mã hóa còn lại

Có một bộ mã hóa thứ hai, có quan hệ họ hàng, được dùng riêng cho việc gửi biểu mẫu HTML: application/x-www-form-urlencoded. Nó gần như giống hệt mã hóa phần trăm URL trừ một chi tiết, khoảng trắng được mã hóa thành + chứ không phải %20. Quy ước này có nguồn gốc từ đặc tả biểu mẫu HTML nguyên thủy và được giữ trong URL Living Standard cho serializer application/x-www-form-urlencoded một cách cụ thể. Bộ giải mã dữ liệu form-encoded phải đảo ngược quy ước: dấu + nguyên văn trong dữ liệu form được mã hóa thành %2B, và dấu + trong chuỗi đã mã hóa được giải mã thành khoảng trắng. API URLSearchParams của JavaScript xử lý quy ước này tự động; encodeURIComponent thì không, nó luôn mã hóa khoảng trắng thành %20. Với chuỗi query lắp ráp thủ công cho action của biểu mẫu HTML, hãy dùng URLSearchParams thay vì gọi encodeURIComponent trên từng giá trị riêng lẻ.

Khi nào công cụ này thực sự cần thiết

Bảo mật: vì sao mã hóa quan trọng vượt ngoài thẩm mỹ

Mã hóa URL không đúng là một nguồn lỗ hổng web cũ kỹ. HTTP response splitting khai thác các dấu xuống dòng chưa được mã hóa (CR, LF, %0D%0A) trong tham số URL được phản chiếu vào header HTTP, cho phép kẻ tấn công tiêm header tùy ý hoặc thậm chí cả một response hoàn chỉnh. Open redirect khai thác việc xử lý URL ngây thơ không giải mã và xác thực đúng URL do người dùng cung cấp trước khi chuyển hướng. Server-side request forgery (SSRF) có thể lạm dụng ký tự đã mã hóa để vượt qua danh sách trắng URL, một biểu thức chính quy chặn "http://internal" sẽ bỏ sót "http://%69nternal" nếu server giải mã sau khi lọc. SQL injection qua tham số URL tự nó không phải là vấn đề mã hóa URL, nhưng trở nên trầm trọng khi dấu nháy đơn và các meta-character SQL khác sống sót đến truy vấn cơ sở dữ liệu. Khuyến nghị của OWASP từ đầu thập niên 2000 là: mã hóa ở biên đầu vào, giải mã ở biên đầu ra, không bao giờ trộn dạng đã mã hóa với dạng chưa mã hóa trong cùng buffer. Công cụ này thực hiện đúng bước mã hóa/giải mã, bạn làm gì với kết quả là tùy bạn, và trách nhiệm bảo mật nằm ở tầng ứng dụng.

Mã hóa hai lần, lỗi thường gặp nhất

Mã hóa hai lần xảy ra khi một chuỗi đã mã hóa được mã hóa thêm lần nữa. Ký tự khoảng trắng trong một URL đã mã hóa là %20; mã hóa nó thêm lần nữa và bạn nhận được %2520 (vì % được mã hóa thành %25). Khi bên nhận giải mã một lần, họ thu được %20 thay vì khoảng trắng. Khi họ giải mã hai lần (trong các trường hợp hiếm hỗ trợ giải mã kép), họ nhận khoảng trắng, nhưng hầu hết bộ phân tích không làm vậy, và URL âm thầm chứa %20 thấy được trong thanh địa chỉ. Cách sửa luôn là: nếu không chắc đầu vào đã mã hóa hay chưa thì giải mã trước, rồi mã hóa đúng một lần. Cùng khuôn mẫu áp dụng trong mã, không bao giờ gọi encodeURIComponent hai lần trên cùng chuỗi. Nếu phải chuyển một giá trị từ ngữ cảnh này sang ngữ cảnh khác, hãy giải mã bộ mã hóa trước đó trước khi mã hóa lại cho ngữ cảnh mới. Nút Đổi chỗ của công cụ này hỗ trợ chu trình chẩn đoán: dán URL nghi ngờ, bấm Decode để xem nó chứa gì, bấm Đổi chỗ, bấm Encode để lấy lại dạng đã mã hóa chuẩn.

Quyền riêng tư: chỉ chạy trong trình duyệt

URL thường nhúng dữ liệu nhạy cảm, token xác thực trong tham số query, định danh người dùng trong đoạn path, truy vấn tìm kiếm chứa bối cảnh cá nhân, giá trị state OAuth, URL webhook bao gồm khóa API. Các trình mã hóa URL phía server giữ một bản sao của mọi URL bạn dán vào trong log của họ. Công cụ này dùng các hàm tích hợp của JavaScript, encodeURIComponent, encodeURI, decodeURIComponentdecodeURI, chạy cục bộ trong tab trình duyệt của bạn. Không có bước upload, không telemetry, không log, hãy kiểm chứng trong tab Network của DevTools khi bạn bấm Encode (không request nào được gửi đi), hoặc đặt trang offline (chế độ máy bay) sau khi đã tải xong và bộ mã hóa vẫn hoạt động. An toàn cho URL chứa token, khóa API, endpoint nội bộ, hoặc bất kỳ URL nào bạn không muốn bị sao vào ổ cứng của người lạ.

Câu hỏi thường gặp

Khi nào tôi nên mã hóa URL văn bản?

Bạn nên mã hóa URL cho văn bản bất cứ khi nào bạn đưa đầu vào của người dùng vào URL, ví dụ: truy vấn tìm kiếm trong chuỗi truy vấn, tên tệp trong đường dẫn hoặc dữ liệu trong tham số yêu cầu API. Nếu không mã hóa, các ký tự đặc biệt có thể phá vỡ cấu trúc URL hoặc gây ra lỗ hổng bảo mật.

Mã hóa kép là gì và làm thế nào để tránh nó?

Mã hóa kép xảy ra khi văn bản đã được mã hóa được mã hóa lại, biến %20 thành %2520. Điều này thường xảy ra khi mã nguồn mã hóa một chuỗi đã được mã hóa. Luôn giải mã trước nếu bạn không chắc văn bản đã được mã hóa hay chưa, sau đó mã hóa một lần.

Công cụ này có an toàn cho các URL nhạy cảm không?

Có. Công cụ này chạy hoàn toàn trong trình duyệt của bạn bằng cách sử dụng các hàm mã hóa tích hợp của JavaScript. Không có dữ liệu nào được gửi đến bất kỳ máy chủ nào. Bạn có thể xác minh điều này bằng cách ngắt kết nối internet, công cụ vẫn sẽ hoạt động.

Vì sao dữ liệu form của tôi có dấu cộng thay vì %20?

Việc gửi biểu mẫu HTML dùng một bộ mã hóa khác nhưng có quan hệ tên là application/x-www-form-urlencoded, mã hóa khoảng trắng thành + chứ không phải %20 theo quy ước lịch sử. Cả hai dạng đều hợp lệ trong chuỗi query URL, các bộ phân tích hiện đại chấp nhận cả hai. API URLSearchParams của JavaScript dùng quy ước form; encodeURIComponent luôn dùng %20. Nếu dữ liệu của bạn cần tương tác với mã xử lý form cũ, hãy dùng URLSearchParams; nếu không, dạng nào cũng được.

Còn ký tự không-ASCII và emoji thì sao?

Mã hóa URL hiện đại dùng UTF-8: mỗi ký tự không-ASCII được chuyển thành biểu diễn UTF-8 nhiều byte, rồi mỗi byte được mã hóa phần trăm. Dấu euro (€, ba byte UTF-8) trở thành %E2%82%AC; một emoji như tên lửa 🚀 (bốn byte) trở thành %F0%9F%9A%80. RFC 3987 (IRI) và WHATWG URL Standard đều chính thức hóa quy ước UTF-8-trước này. Các hệ thống cũ hơn đôi khi dùng Latin-1 hoặc các bộ mã khác; nếu bạn giải mã URL cũ và kết quả trông lộn xộn, nguồn có thể đã dùng bộ mã ký tự khác trước khi mã hóa phần trăm.

Công cụ liên quan