Chuyển đến nội dung

Mã hóa URL

Percent-encoding văn bản để nó đi qua URL nguyên vẹn. Có ba kiểu mã hóa khác nhau cho ba việc khác nhau, và chọn sai là cách các giá trị âm thầm bị hỏng — nên trang sẽ cho bạn biết bạn cần loại nào.

  • Không bao giờ lưu trữ
  • Không xếp hàng, không phải chờ
  • Không cần đăng ký, không watermark
Đã mã hóa

Đã mã hóa sẽ hiện ở đây.

Cách hoạt động

1

Dán văn bản

Bất kỳ văn bản nào, bằng bất kỳ ngôn ngữ nào. Văn bản được mã hóa dưới dạng UTF-8, đúng thứ mọi máy chủ hiện đại mong đợi.

2

Chọn mục đích

Một giá trị đưa vào query string, cả một URL đã ghép hoàn chỉnh, hoặc dữ liệu gửi từ biểu mẫu. Sự khác biệt là quan trọng và mỗi loại đều được giải thích.

3

Sao chép kết quả

Mã hóa từng dòng nếu bạn có cả một danh sách cần xử lý cùng lúc.

Ba đáp án đúng, và vì sao một nút bấm là sai

Percent-encoding thay một ký tự bằng dấu % và giá trị byte của nó ở dạng hex. Đặc tả chia ký tự thành ba nhóm, và mọi điều khó hiểu ở đây đều bắt nguồn từ đó. Các ký tự không dành riêng (unreserved) — chữ cái, chữ số, gạch nối, dấu chấm, gạch dưới và dấu ngã — không bao giờ cần mã hóa. Các ký tự dành riêng (reserved) — dấu gạch chéo, dấu hỏi, dấu &, dấu bằng và dấu hai chấm tạo nên cấu trúc của URL — phải được mã hóa *khi chúng là dữ liệu* và không được mã hóa *khi chúng là cấu trúc*. Mọi ký tự khác luôn được mã hóa.

Đó là lý do không có một đáp án đúng duy nhất. Mã hóa cả một URL phải giữ nguyên dấu gạch chéo và dấu hỏi, nếu không địa chỉ sẽ không còn là địa chỉ. Mã hóa một giá trị để đưa vào tham số query phải thoát dấu & và dấu bằng, nếu không một giá trị chứa chúng sẽ bị tách thành hai tham số. Mã hóa một đoạn đường dẫn phải thoát dấu gạch chéo, nếu không một tên file có dấu gạch chéo sẽ thành hai thư mục. Một nút Mã hóa duy nhất chỉ chọn một trong ba cách đó và sai trong hai phần ba trường hợp còn lại — thường là âm thầm, và thường theo kiểu chỉ lộ ra với dữ liệu đầu vào khác thường.

Dấu cách là ký tự có nhiều lịch sử nhất. Trong URL nó là %20. Trong một biểu mẫu HTML được gửi đi, nó là +, một kiểu mã hóa riêng, cũ hơn, vẫn tồn tại vì biểu mẫu đã hoạt động như vậy từ năm 1994. Cả hai đều đúng trong ngữ cảnh của mình và không cái nào đúng trong ngữ cảnh của cái kia, đó là lý do dấu cộng trong query string mơ hồ theo cách mà cẩn thận đến đâu ở phía mã hóa cũng không khắc phục được.

Văn bản không phải ASCII được mã hóa thành UTF-8 trước rồi mới mã hóa từng byte, nên một chữ cái có dấu thành hai chuỗi phần trăm còn một emoji thành bốn. Mã hóa hai lần là lỗi kinh điển: mã hóa thứ đã được mã hóa sẽ biến mọi dấu % thành %25, nên %20 thành %2520 và phía bên kia nhận được một dấu phần trăm theo đúng nghĩa đen. Nếu một URL đầy %25, nó đã đi qua bộ mã hóa thừa một lần.

Khi bạn cần công cụ khác

Trong code, hãy dùng hàm có sẵn của ngôn ngữ và chọn nó một cách có chủ đích như trang này bắt bạn làm. JavaScript có encodeURI cho cả địa chỉ và encodeURIComponent cho giá trị; Python có urllib.parse.quote với tham số safe mặc định giữ nguyên dấu gạch chéo; PHP phân biệt rawurlencode với urlencode, hai hàm khác nhau đúng ở vấn đề dấu cách hay dấu cộng nói trên. Tốt hơn nữa, hãy tạo URL bằng một kiểu dữ liệu URL thay vì ghép chuỗi, và câu hỏi này sẽ biến mất.

Trên dòng lệnh, jq -rR @uri mã hóa an toàn và xử lý được cả danh sách, còn curl --data-urlencode tạo tham số được mã hóa đúng mà bạn không cần nghĩ mình đang ở trường hợp nào trong ba trường hợp — đó là nơi duy nhất việc này thực sự dễ dàng.

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

Tôi nên dùng loại nào trong ba loại?

Gần như luôn là “Một giá trị”. Dùng nó khi bạn mã hóa MỘT giá trị sắp được đưa vào query string hoặc một đoạn đường dẫn — từ khóa tìm kiếm, địa chỉ email, đích chuyển hướng. Đây là loại duy nhất trong ba loại thoát các ký tự &, =, ? và /, chính là điều ngăn giá trị của bạn thoát ra khỏi tham số và biến thành hai tham số. Chỉ dùng “Cả một URL” khi bạn đã có một URL hoàn chỉnh và chỉ muốn làm sạch các ký tự không an toàn; nó cố ý giữ nguyên các ký tự cấu trúc để URL vẫn là URL. Dùng “Dữ liệu biểu mẫu” khi bạn tạo phần thân application/x-www-form-urlencoded, nơi dấu cách là + thay vì %20.

Vì sao dấu “&” làm hỏng URL của tôi?

Vì nó chưa được mã hóa, và & là cách query string phân tách tham số này với tham số tiếp theo. Giá trị “Smith & Sons” nối thẳng vào ?company= sẽ đến máy chủ thành company=Smith cùng một tham số thứ hai, rỗng, tên là “Sons”. Đây là lỗi URL phổ biến nhất, và mã hóa theo kiểu “Một giá trị” là cách sửa — nó biến & thành %26 để giá trị vẫn là một giá trị.

Vì sao dấu “+” của tôi biến thành dấu cách?

Vì trong query string, + nghĩa là dấu cách — một quy tắc thừa hưởng từ biểu mẫu HTML mà chưa ai gỡ bỏ được. Vì vậy một dấu cộng thật trong dữ liệu của bạn, trong số điện thoại hay chuỗi Base64, sẽ bị máy chủ nhận hiểu là dấu cách. Mã hóa theo kiểu “Một giá trị” sẽ thoát nó thành %2B, và nó đến nơi nguyên vẹn.

Công cụ có xử lý được ngôn ngữ khác và emoji không?

Có. Văn bản được chuyển sang UTF-8 trước rồi được percent-encoding từng byte một, đúng như RFC 3986 yêu cầu và mọi máy chủ hiện đại mong đợi. Tiếng Nhật, tiếng Ả Rập, chữ Latin có dấu và emoji đều được mã hóa rồi giải mã lại chính xác.

Vì sao ! ' ( ) * được mã hóa ở đây trong khi công cụ khác để nguyên?

Vì hàm encodeURIComponent có sẵn của trình duyệt để nguyên năm ký tự đó, trong khi RFC 3986 xếp chúng vào nhóm dành riêng. Một số máy chủ và framework coi chúng là ký tự cấu trúc, nên một giá trị chứa chúng có thể bị đọc sai. Mã hóa chúng không gây hại gì — chúng giải mã lại giống hệt ở mọi nơi — và loại bỏ được một nhóm lỗi hiếm gặp, khó chẩn đoán. Đây là điều các cách triển khai cẩn thận đều làm.

Văn bản của tôi có bị lưu ở đâu không?

Không. Không lưu trữ gì cả và không có yêu cầu nào được gửi đi. Bạn có thể ngắt kết nối internet sau khi trang tải xong và nó vẫn hoạt động.

Nên biết: Có ba đáp án đúng khác nhau và trang này bắt bạn chọn, vì nút Mã hóa duy nhất thường thấy sai đến hai phần ba số lần. Mã hóa cả một URL, một tham số query và một đoạn đường dẫn sẽ thoát các ký tự khác nhau; dùng sai loại sẽ âm thầm làm hỏng dấu gạch chéo, dấu cộng hoặc dấu &.

Đặt công cụ này lên website của bạn

Miễn phí cho mọi blog, trang lớp học hay bài viết hướng dẫn. Chỉ cần dán một đoạn mã là khách truy cập có thể dùng ngay trên trang của bạn.