Mã hóa và giải mã URL

Acrafto Team Nhà phát triển
Cập nhật
Mã hóa như

Dùng cho một giá trị truy vấn hoặc một đoạn đường dẫn. Mã hóa mọi thứ trừ chữ cái, chữ số và - _ . ! ~ * ' ( ), giống encodeURIComponent.

Kết quả

Mọi thứ chạy ngay trong trình duyệt của bạn và không có gì bạn dán vào bị tải lên. Điều đó quan trọng, vì URL thường chứa token và mã phiên.

Mã hóa và giải mã URL (URL encode / decode) trực tuyến ngay khi bạn gõ: công cụ biến dấu cách, chữ có dấu và các ký hiệu như & hay ? thành chuỗi mã hóa phần trăm kiểu %20, rồi đổi chúng lại thành văn bản dễ đọc. Tab thứ hai là trình phân tích URL. Nó tách bất kỳ địa chỉ nào thành giao thức, máy chủ, đường dẫn và các tham số truy vấn mà bạn có thể sửa, tắt hoặc xóa thẻ theo dõi, rồi ghi lại URL đã được mã hóa đúng cho bạn. Mọi thứ diễn ra ngay trong trình duyệt của bạn.

Cách URL encode và decode văn bản

  1. Nhập hoặc dán vào ô ở tab Mã hóa / Giải mã. Phần Kết quả cập nhật sau mỗi lần gõ phím.
  2. Chọn Hướng. Mã hóa làm văn bản an toàn để đưa vào URL, Giải mã đổi caf%C3%A9%20au%20lait về lại café au lait. Nếu bạn dán văn bản có các chuỗi như %20 vào ô trống, công cụ tự chuyển sang Giải mã (nút Mã hóa thay vào đó chuyển ngược lại). Văn bản thường cần mã hóa mà dán vào chế độ Giải mã cũng được chuyển sang Mã hóa theo cách tương tự, với nút Giải mã thay vào đó.
  3. Khi mã hóa, hãy chọn ở mục Mã hóa như loại văn bản của bạn (xem phần tiếp theo). Mặc định, Giá trị tham số, phù hợp cho một giá trị truy vấn đơn lẻ.
  4. Sao chép đưa kết quả vào bộ nhớ tạm. Hoán đổi chuyển kết quả vào ô nhập và đảo hướng. Đây là cách kiểm tra nhanh hai chiều: giải mã thứ bạn vừa mã hóa phải trả về đúng văn bản ban đầu.

Mọi ký tự mà công cụ đã thay đổi đều được tô sáng trong kết quả. Di chuột lên một ký tự để xem ký tự đó, điểm mã Unicode và các byte của nó, ví dụ é U+00E9 %C3%A9. Bên dưới các ô là số Ký tự, Byte UTF-8 và Ký tự đã mã hóa (hoặc Ký tự đã giải mã). Thử ví dụ nạp câu Giảm giá 50 %, cà phê & bánh flan? Ngon lắm!, có 44 ký tự nhưng 52 byte UTF-8, vì các chữ như à, á hay ê chiếm hai byte, còn những chữ nằm trong khối Latin mở rộng bổ sung của tiếng Việt như ả hay ắ chiếm ba byte.

Khi mã hóa, Từng dòng riêng mã hóa mỗi dòng độc lập và giữ nguyên các chỗ xuống dòng, rất hợp với danh sách giá trị hoặc liên kết. Nếu không bật, chỗ xuống dòng cũng bị mã hóa và thành %0A. Khi văn bản là một URL có tham số, công cụ đề nghị Tách thành các phần, nút này mở địa chỉ đó trong tab phân tích.

Mã hóa tham số URL, cả URL hoặc dữ liệu biểu mẫu

Không phải ký tự nào cũng cần được mã hóa ở mọi nơi. Dấu gạch chéo ngăn cách các thư mục trong đường dẫn nhưng chỉ là dữ liệu thông thường bên trong giá trị tham số, nên kết quả đúng phụ thuộc vào thứ bạn mã hóa. Mã hóa như có bốn chế độ:

  • Giá trị tham số hoạt động như encodeURIComponent của JavaScript và phù hợp cho một giá trị truy vấn hoặc một đoạn đường dẫn. Nó mã hóa mọi thứ trừ chữ cái, chữ số và - _ . ! ~ * ' ( ), nên dấu &, =, / hay ? nằm trong giá trị không thể làm hỏng URL. Mã hóa café & crème cho ra caf%C3%A9%20%26%20cr%C3%A8me, sẵn sàng để đặt sau q=.
  • Cả URL dành cho một địa chỉ hoàn chỉnh chỉ cần làm sạch. Nó mã hóa dấu cách, ký tự ngoài ASCII, ký tự điều khiển, dấu huyền (backtick) và " < > \ ^ { | }, đồng thời giữ lại mọi thứ tạo nên cấu trúc của URL: : / ? # [ ] @ ! $ & ' ( ) * + , ; =. Vì vậy https://example.com/search?q=café au lait&lang=fr trở thành https://example.com/search?q=caf%C3%A9%20au%20lait&lang=fr. Các chuỗi đã được mã hóa sẵn được giữ nguyên, còn một dấu % đứng riêng thành %25. Đây là điểm khác với encodeURI của JavaScript, vốn biến %20 có sẵn thành %2520 và mã hóa cả dấu ngoặc vuông của địa chỉ IPv6 như http://[2001:db8::1]:8080/.
  • Dữ liệu biểu mẫu theo định dạng application/x-www-form-urlencoded (bằng tiếng Anh) mà biểu mẫu HTML và URLSearchParams tạo ra. Dấu cách thành +, và chỉ chữ cái, chữ số cùng * - . _ không bị mã hóa, nên ! ' ( ) ~ cũng được mã hóa.
  • RFC 3986 nghiêm ngặt chỉ để các ký tự không dành riêng của RFC 3986 (bằng tiếng Anh) không bị mã hóa: chữ cái, chữ số và - . _ ~. OAuth 1.0 (RFC 5849) và AWS Signature Version 4 yêu cầu đúng dạng này, vì chữ ký chỉ khớp khi cả hai bên mã hóa ! hay * giống hệt nhau.

Cùng các ký tự đó trong từng chế độ:

Ký tựGiá trị tham sốCả URLDữ liệu biểu mẫuRFC 3986 nghiêm ngặt
dấu cách%20%20+%20
&%26&%26%26
/%2F/%2F%2F
+%2B+%2B%2B
~~~%7E~
!!!%21%21
****%2A
é%C3%A9%C3%A9%C3%A9%C3%A9

Văn bản luôn được mã hóa theo UTF-8 và các chữ số hex luôn viết hoa. Nếu dữ liệu nhập đã chứa các chuỗi như %20, một ghi chú sẽ báo điều đó và đề nghị Giải mã thay vào đó, để bạn không mã hóa văn bản hai lần do nhầm.

Để truyền JSON trong một tham số truy vấn, hãy thu gọn nó bằng trình định dạng JSON rồi mã hóa với Giá trị tham số: {"id":7,"tags":["a","b"]} thành %7B%22id%22%3A7%2C%22tags%22%3A%5B%22a%22%2C%22b%22%5D%7D. Làm ngược lại cũng được: giải mã tham số ở đây, rồi định dạng nó ở đó.

Lỗi URL decode: dấu cộng, %2520 và chuỗi hỏng

Giải mã thường chạy suôn sẻ, nhưng có bốn tình huống hay làm người ta vấp. Công cụ xử lý từng tình huống thay vì dừng lại với một thông báo lỗi:

  • Dấu cộng đại diện cho dấu cách trong dữ liệu biểu mẫu và hầu hết chuỗi truy vấn. Giải mã + thành dấu cách được bật theo mặc định, nên caf%C3%A9+au+lait được giải mã thành café au lait. Với một URL đầy đủ, chỉ các dấu cộng sau dấu ? được tính là dấu cách, vì trong đường dẫn dấu cộng là một ký tự bình thường. Hãy tắt tùy chọn này khi dấu cộng mang nghĩa đen. Dấu cộng đã được mã hóa thành %2B luôn giữ là dấu cộng.
  • Mã hóa kép xảy ra khi hai đoạn mã liên tiếp cùng mã hóa một giá trị, điều mà RFC 3986 cảnh báo rõ ràng. Mỗi % thành %25, nên dấu cách từ %20 biến thành %2520. Nếu kết quả giải mã vẫn còn các chuỗi như %20, công cụ cho biết văn bản có lẽ đã bị mã hóa hai lần và đề nghị Giải mã lần nữa.
  • Một chuỗi không hợp lệ, tức dấu % không theo sau bởi hai chữ số hex như trong 100% hay %G1, khiến decodeURIComponent của JavaScript ném lỗi URIError. Ở đây các chuỗi như vậy được giữ nguyên, đánh dấu đỏ và được đếm, còn phần văn bản còn lại vẫn được giải mã.
  • Các liên kết Latin-1 cũ đến từ thời trước UTF-8, khi một số trang mã hóa é thành một byte duy nhất %E9. caf%E9 không phải UTF-8 hợp lệ, nên decodeURIComponent báo lỗi và unquote của Python trả về caf kèm ký tự thay thế U+FFFD. Công cụ đọc các byte như vậy theo Windows-1252, giải mã caf%E9 thành café và thêm một ghi chú cho biết điều đó.

Ký tự điều khiển trong văn bản đã giải mã, như tab hay byte null, được hiển thị bằng các ký hiệu nhìn thấy được như ␉ và ␀, nhưng Sao chép sao chép văn bản thật.

Trình phân tích URL: tách URL và sửa tham số truy vấn

Dán một địa chỉ vào ô URL ở tab Phân tích & sửa URL và nó được tách thành Giao thức, Máy chủ, Cổng, Đường dẫn và Fragment, cộng thêm Tên người dùng và Mật khẩu khi URL có chứa chúng. Các giá trị được hiển thị ở dạng đã giải mã, nên tab này cũng là cách nhanh nhất để giải mã tham số URL: bạn đọc được giày chạy bộ thay vì gi%C3%A0y+ch%E1%BA%A1y+b%E1%BB%99. Việc chỉnh sửa hoạt động hai chiều, như thanh địa chỉ và bảng tham số trong Postman. Đổi một trường và URL được viết lại ngay, mã hóa đúng; đổi URL và tất cả các phần được đọc lại. Những phần bạn không đụng vào giữ nguyên từng ký tự một.

Bảng Tham số truy vấn liệt kê mọi tham số với Tên và Giá trị của nó. Bỏ chọn Đưa vào URL để loại một tham số khỏi URL mà không cần xóa, rất hữu ích khi bạn đang tìm tham số làm hỏng một yêu cầu. Thêm tham số, Xóa tham số và Sắp xếp A đến Z làm đúng như tên gọi. Tên lặp lại như tag=a&tag=b và tên không có giá trị như ?debug đều được giữ. Dấu cách trong tham số quyết định dấu cách được viết là %20 hay +; mặc định nó theo URL bạn đã dán.

Liên kết đăng nhập và thanh toán thường mang một URL thứ hai bên trong một tham số, được mã hóa để ? và & của nó không lẫn với những dấu của URL ngoài:

https://auth.example.com/authorize?client_id=abc&redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback%3Ftab%3D2

Một giá trị bản thân là URL, thường nằm trong redirect_uri, return, url hoặc next, sẽ có nút Sửa URL bên trong. Địa chỉ bên trong https://app.example.com/callback?tab=2 mở thành một cấp riêng với các phần và tham số riêng, thanh đường dẫn (URL chính › redirect_uri) đưa bạn quay lại, và mọi thay đổi đều được mã hóa ngược vào URL ngoài. Sao chép URL chính sao chép kết quả. Cách này dùng được sâu nhiều cấp.

Khi phần sau dấu # trông như các tham số, ví dụ #access_token=...&state=... trong luồng implicit của OAuth hoặc #/search?q=shoes trong định tuyến của ứng dụng một trang, bảng thứ hai, Tham số fragment, cũng liệt kê chúng.

Trình phân tích cũng chỉ ra các vấn đề: URL không có giao thức, mà trình duyệt coi là liên kết tương đối; cổng nằm ngoài khoảng 0 đến 65535; và các ký tự bắt buộc phải mã hóa, như dấu cách, chữ có dấu, " hoặc <, mà Mã hóa chúng sửa chỉ trong một bước. Văn bản không có địa chỉ, như a=1&b=2, được đọc như một chuỗi truy vấn. Với tên miền quốc tế hóa, công cụ hiển thị dạng Punycode mà DNS và trình duyệt dùng, nên münchen.de thành xn--mnchen-3ya.de, còn tên miền bắt đầu bằng xn-- được hiển thị dạng dễ đọc.

Sao chép URL sao chép địa chỉ hoàn chỉnh, Mở mở nó trong tab mới (chỉ với liên kết http và https), và Sao chép dạng JSON cho bạn các tham số dưới dạng một đối tượng JSON, trong đó các tên lặp lại được gom thành một mảng.

Xóa UTM và các tham số theo dõi khỏi URL

Liên kết từ bản tin email, quảng cáo và mạng xã hội mang các tham số chỉ để cho trang biết khách truy cập đến từ đâu. Các tham số UTM (bằng tiếng Anh) utm_source, utm_medium, utm_campaign, utm_term và utm_content bắt nguồn từ Urchin, tiền thân của Google Analytics. Các ID nhấp chuột như fbclid (Facebook), gclid (Google Ads) và msclkid (Microsoft Advertising) do chính các nền tảng gắn vào.

Trình phân tích đánh dấu chúng bằng thẻ theo dõi, và Xóa theo dõi (n) xóa tất cả cùng lúc. Ngoài mọi tham số utm_*, nó nhận ra hơn 20 tham số khác, như ttclid (TikTok), mc_cid (Mailchimp) và _hsenc (HubSpot). Các tham số mà trang cần vẫn được giữ nguyên: trong liên kết cửa hàng của Thử ví dụ, Xóa theo dõi (4) xóa utm_source, utm_medium, utm_campaign và fbclid và giữ lại q, size, return cùng fragment #reviews.

Một liên kết sắp được đưa vào mã QR nên được làm sạch ở đây trước. Không có tham số theo dõi, nó ngắn hơn, và liên kết ngắn hơn cho mã ít dày đặc hơn, dễ quét hơn.

Mã hóa phần trăm là gì và ký tự thành %XX như thế nào

Mã hóa phần trăm (bằng tiếng Anh), còn gọi là URL encoding, viết một ký tự thành % theo sau là hai chữ số thập lục phân. Một URL chỉ được chứa một tập ký tự ASCII hạn chế, và một số trong đó có nhiệm vụ riêng: ? bắt đầu phần truy vấn, & ngăn cách các tham số, # bắt đầu fragment. RFC 3986 gọi chúng là ký tự dành riêng (: / ? # [ ] @ và ! $ & ' ( ) * + , ; =). Chữ cái, chữ số và - . _ ~ là ký tự không dành riêng và không bao giờ cần mã hóa. Mọi thứ còn lại, và mọi ký tự dành riêng được dùng như dữ liệu thông thường, đều được mã hóa.

Các ký tự ngoài ASCII trước tiên được chuyển thành byte UTF-8, và mỗi byte có %XX riêng:

  • é là U+00E9, UTF-8 lưu thành hai byte C3 A9, nên nó thành %C3%A9.
  • € là U+20AC, ba byte: %E2%82%AC.
  • Một emoji như U+1F600 (mặt cười toe toét) chiếm bốn byte: %F0%9F%98%80.

%c3%a9 và %C3%A9 có nghĩa như nhau, nhưng RFC 3986 khuyến nghị viết hoa, đúng như công cụ này ghi ra. Bảng mã hóa phần trăm của những ký tự bạn gặp nhiều nhất:

Ký tựĐã mã hóaKý tựĐã mã hóa
dấu cách%20+%2B
!%21,%2C
"%22/%2F
#%23:%3A
$%24;%3B
%%25=%3D
&%26?%3F
'%27@%40
(%28[%5B
)%29]%5D
*%2Angắt dòng%0A

URL encoding trong JavaScript, Python và PHP

Ngôn ngữ nào cũng có hàm cho việc này, và chúng khác nhau chủ yếu ở cách xử lý dấu cách, dấu gạch chéo và ! ' ( ) * ~.

JavaScript có encodeURIComponent (bằng tiếng Anh) cho một giá trị, encodeURI cho cả địa chỉ và URLSearchParams cho mã hóa biểu mẫu:

encodeURIComponent("café & crème")                     // "caf%C3%A9%20%26%20cr%C3%A8me"
encodeURI("https://example.com/a b?q=café")            // "https://example.com/a%20b?q=caf%C3%A9"
new URLSearchParams({ q: "café & crème" }).toString()  // "q=caf%C3%A9+%26+cr%C3%A8me"
decodeURIComponent("caf%C3%A9")                        // "café"

decodeURIComponent không đổi + thành dấu cách, và nó ném lỗi URIError với chuỗi không hợp lệ như 100%.

Trong Python, các hàm nằm trong urllib.parse. quote mặc định giữ / (safe='/') và nếu không thì mã hóa mọi thứ trừ các ký tự không dành riêng của RFC 3986. quote_plus viết dấu cách thành + và mã hóa cả /:

from urllib.parse import quote, quote_plus, urlencode, unquote_plus

quote("café & crème/brûlée")       # 'caf%C3%A9%20%26%20cr%C3%A8me/br%C3%BBl%C3%A9e'
quote("a b/c", safe="")            # 'a%20b%2Fc'
quote_plus("café & crème/brûlée")  # 'caf%C3%A9+%26+cr%C3%A8me%2Fbr%C3%BBl%C3%A9e'
urlencode({"q": "café & crème", "page": 2})  # 'q=caf%C3%A9+%26+cr%C3%A8me&page=2'
unquote_plus("caf%C3%A9+au+lait")  # 'café au lait'

Trong PHP, urlencode mã hóa như một biểu mẫu HTML và viết dấu cách thành +, còn rawurlencode theo RFC 3986 và viết %20:

urlencode("café & crème");     // "caf%C3%A9+%26+cr%C3%A8me"
rawurlencode("café & crème");  // "caf%C3%A9%20%26%20cr%C3%A8me"

rawurlencode cho cùng kết quả như RFC 3986 nghiêm ngặt. urlencode khớp với Dữ liệu biểu mẫu trừ *, mà nó mã hóa thành %2A.

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

Dấu cách nên mã hóa thành %20 hay +?

%20 dùng được ở mọi nơi trong URL. Dấu + chỉ có nghĩa là dấu cách trong chuỗi truy vấn và trong dữ liệu biểu mẫu, định dạng mà biểu mẫu HTML gửi đi. Trong đường dẫn, + là dấu cộng bình thường, nên /a+b vẫn là /a+b. Khi một giá trị truy vấn cần dấu cộng thật, hãy viết nó là %2B. Trong công cụ, Dữ liệu biểu mẫu viết dấu cách thành + còn ba chế độ kia viết thành %20.

%20, %2F và %3D trong URL nghĩa là gì?

Đó là các ký tự đã được mã hóa: %20 là dấu cách, %2F là dấu gạch chéo và %3D là dấu bằng. Những mã bạn hay gặp khác là %26 (&), %3F (?), %3A (:), %2C (dấu phẩy) và %27 (dấu nháy đơn). Hai chữ số là mã của ký tự ở dạng thập lục phân. Chữ có dấu và các ký tự ngoài ASCII khác chiếm từ hai đến bốn cặp như vậy, như %C3%A9 cho é. Hãy dán cả chuỗi vào công cụ giải mã để đọc nó.

encodeURI và encodeURIComponent khác nhau thế nào?

encodeURI dành cho cả một địa chỉ và để yên các ký tự tạo cấu trúc cho nó, như : / ? # & =. encodeURIComponent dành cho một phần, một giá trị tham số hoặc một đoạn đường dẫn, và mã hóa cả những ký tự đó, nên https://example.com/?a=1&b=2 thành https%3A%2F%2Fexample.com%2F%3Fa%3D1%26b%3D2. Trong công cụ này, Giá trị tham số tương ứng với encodeURIComponent, còn Cả URL giống encodeURI nhưng giữ các chuỗi có sẵn như %20 thay vì biến chúng thành %2520.

Làm sao để xóa tham số UTM khỏi URL?

Dán liên kết vào tab Phân tích & sửa URL và bấm Xóa theo dõi (n). Nút này xóa cùng lúc mọi thẻ utm_* và các ID nhấp chuột như fbclid và gclid. Sau đó bấm Sao chép URL. Để chỉ bỏ một vài tham số, hãy dùng Xóa tham số ở những dòng bạn không muốn giữ.

Mã hóa URL có giống mã hóa bảo mật hay Base64 không?

Không. Mã hóa URL không che giấu gì: ai cũng giải mã được caf%C3%A9 về café, nên nó không bao giờ bảo vệ được mật khẩu hay token. Nó chỉ làm cho các ký tự an toàn khi dùng trong một địa chỉ. Base64 là một kiểu mã hóa khác, biến mọi dữ liệu, kể cả tệp nhị phân, thành chuỗi gồm 64 ký tự. Một chuỗi Base64 trong URL vẫn cần mã hóa +, / và =, trừ khi bạn dùng biến thể URL safe mà công cụ mã hóa và giải mã Base64 có thể tạo ra.

URL tôi dán vào có bị tải lên hay lưu lại không?

Không. Việc mã hóa, giải mã và phân tích chạy trong trình duyệt của bạn, và không có gì bạn dán vào được gửi đến máy chủ. Điều này quan trọng, vì URL thường mang access token, ID phiên hoặc mã đặt lại mật khẩu. Trình duyệt chỉ ghi nhớ tab và các tùy chọn bạn đã chọn, không bao giờ nhớ văn bản. Thứ duy nhất tải địa chỉ là Mở, nút mở nó trong tab mới giống như khi bạn bấm vào liên kết.

Thêm nhiều công cụ cho lập trình viên nằm trong danh mục Nhà phát triển, còn các công cụ biến một định dạng thành định dạng khác được gom dưới Trình chuyển đổi. Để tìm điểm khác nhau giữa hai URL dài, chẳng hạn một lệnh gọi API chạy được và một lệnh bị lỗi, hãy dán chúng vào công cụ so sánh văn bản và so sánh theo ký tự.

Tôi sẽ đánh giá cao nếu bạn có thể chia sẻ những trang này với bạn bè, đánh dấu trang hoặc liên kết đến chúng. Cảm ơn! 🙏