URL mã hóa ký tự khoảng trắng: + hoặc% 20?


723

Khi nào một không gian trong một URL được mã hóa +và khi nào nó được mã hóa thành %20?


2
Câu hỏi này sẽ hữu ích hơn khi một số câu hỏi dành riêng cho ngôn ngữ, phải không?
squarecandy


3
@user câu hỏi bạn liên kết đến đã được hỏi sau đó, làm cho nó thành bản sao, không phải câu hỏi này.
Tinh tinh hiếu chiến

Câu trả lời:


425

Từ Wikipedia (nhấn mạnh và liên kết được thêm vào):

Khi dữ liệu đã được nhập vào biểu mẫu HTML được gửi, tên và giá trị của trường biểu mẫu được mã hóa và gửi đến máy chủ trong thông báo yêu cầu HTTP bằng phương thức GET hoặc POST, hoặc, theo lịch sử, qua email. Mã hóa được sử dụng theo mặc định dựa trên phiên bản đầu tiên của quy tắc mã hóa phần trăm URI chung, với một số sửa đổi như chuẩn hóa dòng mới và thay thế khoảng trắng bằng "+" thay vì "% 20". Kiểu dữ liệu MIME được mã hóa theo cách này là application / x-www-form-urlencoding và hiện được xác định (vẫn theo cách rất lỗi thời) trong thông số kỹ thuật HTML và XForms.

Vì vậy, phần trăm mã hóa thực sự sử dụng %20trong khi dữ liệu biểu mẫu trong URL ở dạng được sửa đổi sử dụng +. Vì vậy, rất có thể bạn chỉ nhìn thấy +trong các URL trong chuỗi truy vấn sau một ?.


2
Vì vậy, mã hóa + về mặt kỹ thuật sẽ là mã hóa đa dữ liệu / biểu mẫu dữ liệu, trong khi mã hóa phần trăm là ứng dụng / x-www-form-urlencoding?
BC.

17
@BC: không - multipart/form-datasử dụng mã hóa MIME; application/x-www-form-urlencodedsử dụng +và sử dụng URI được mã hóa đúng cách %20.
McDowell

8
"Vì vậy, rất có thể bạn chỉ thấy + trong URL trong chuỗi truy vấn sau một?" Là một cách đánh giá thấp. Bạn sẽ không bao giờ thấy "+" trong phần đường dẫn của URL vì nó sẽ không làm những gì bạn mong đợi (không gian).
Adam Gent

34
Về cơ bản: Mục tiêu của việc gửi GET là http://www.bing.com/search?q=hello+worldvà một tài nguyên có khoảng trống trong tênhttp://camera.phor.net/cameralife/folders/2012/2012-06%20Pool%20party/
William Entriken

8
Lưu ý rằng đối với các liên kết email, bạn cần% 20 chứ không phải + sau ?. Ví dụ , mailto:support@example.org?subject=I%20need%20help. Nếu bạn đã thử với +, email sẽ mở bằng + es thay vì dấu cách.
Sygmoral

288

Sự nhầm lẫn này là do các URL vẫn bị 'hỏng' cho đến ngày nay.

Lấy ví dụ " http://www.google.com ". Đây là một URL. URL là một Bộ định vị tài nguyên thống nhất và thực sự là một con trỏ tới một trang web (trong hầu hết các trường hợp). Các URL thực sự có cấu trúc được xác định rất rõ kể từ thông số kỹ thuật đầu tiên vào năm 1994.

Chúng tôi có thể trích xuất thông tin chi tiết về URL " http://www.google.com ":

+---------------+-------------------+
|      Part     |      Data         |
+---------------+-------------------+
|  Scheme       | http              |
|  Host         | www.google.com    |
+---------------+-------------------+

Nếu chúng ta xem một URL phức tạp hơn, chẳng hạn như:

" https: // bob: bulk@www.lunatech.com: 8080 / tệp; p = 1? q = 2 # thứ ba "

chúng ta có thể trích xuất các thông tin sau:

+-------------------+---------------------+
|        Part       |       Data          |
+-------------------+---------------------+
|  Scheme           | https               |
|  User             | bob                 |
|  Password         | bobby               |
|  Host             | www.lunatech.com    |
|  Port             | 8080                |
|  Path             | /file;p=1           |
|  Path parameter   | p=1                 |
|  Query            | q=2                 |
|  Fragment         | third               |
+-------------------+---------------------+

https://bob:bobby@www.lunatech.com:8080/file;p=1?q=2#third
\___/   \_/ \___/ \______________/ \__/\_______/ \_/ \___/
  |      |    |          |          |      | \_/  |    |
Scheme User Password    Host       Port  Path |   | Fragment
        \_____________________________/       | Query
                       |               Path parameter
                   Authority

Các nhân vật dành riêng là khác nhau cho mỗi phần.

Đối với URL HTTP, một khoảng trắng trong phần phân đoạn đường dẫn phải được mã hóa thành "% 20" (không, hoàn toàn không phải là "+"), trong khi ký tự "+" trong phần phân đoạn đường dẫn có thể không được mã hóa.

Bây giờ trong phần truy vấn, các khoảng trắng có thể được mã hóa thành "+" (để tương thích ngược: không cố tìm kiếm nó trong tiêu chuẩn URI) hoặc "% 20" trong khi ký tự "+" (do sự mơ hồ này ) phải được thoát đến "% 2B".

Điều này có nghĩa là chuỗi "blue + light blue" phải được mã hóa khác nhau trong phần đường dẫn và truy vấn:

" http://example.com/blue+light%20blue?blue%2Blight+blue ".

Từ đó bạn có thể suy luận rằng việc mã hóa một URL được xây dựng đầy đủ là không thể nếu không có nhận thức cú pháp về cấu trúc URL.

Điều này sôi xuống:

Bạn nên có %20trước ?+sau.

Nguồn


>> bạn nên có% 20 trước? và + sau Xin lỗi vì câu hỏi ngớ ngẩn. Tôi biết một chút bằng cách nào đó tham số hashtag được sử dụng sau "?" tham số dấu hỏi. Mặc dù nó khác đi một chút vì sử dụng "#" không tải lại trang. Nhưng tôi đã cố sử dụng ký hiệu% 20 và + sau hashtag "#" và có vẻ như nó không hoạt động. Cái nào cần được sử dụng sau "#"?
Philcyb

@Philcyb Bạn có thể muốn đọc này en.wikipedia.org/wiki/Percent-encoding
Matas Vaitkevicius

Phần truy vấn có thực sự có một tiêu chuẩn "chính thức" không? Tôi nghĩ về cơ bản phần đó là ứng dụng cụ thể. 99,99% ứng dụng sử dụng key1=value1&key1=value2trong đó các khóa và giá trị được mã hóa theo bất kỳ quy tắc nào encodeURIComponenttuân theo nhưng AFAIK nội dung của phần truy vấn hoàn toàn tùy thuộc vào ứng dụng. Khác sau đó nó chỉ đi đến đầu tiên #không có mã hóa chính thức.
gman

Một câu trả lời trùng lặp cho câu hỏi trùng lặp! Nhưng hmm, ok, tôi đã cho cả hai.
Vladimir Vukanac

3
Đó là ghi nhãn thành phần ASCII là sử thi.
jsejcksn

25

Tôi muốn giới thiệu %20.

Bạn có khó mã hóa chúng không?

Điều này không nhất quán trên các ngôn ngữ, mặc dù. Nếu tôi không nhầm, trong PHP urlencode()xử lý các khoảng trắng như +trong khi Python urlencode()xử lý chúng như %20.

BIÊN TẬP:

Có vẻ như tôi đã nhầm. Python urlencode()(ít nhất là trong 2.7.2) sử dụng quote_plus()thay vì quote()và do đó mã hóa các khoảng trắng là "+". Dường như đề xuất của W3C là "+" theo đây: http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1

Và trên thực tế, bạn có thể theo dõi cuộc tranh luận thú vị này trên trình theo dõi vấn đề của chính Python về những gì sẽ sử dụng để mã hóa không gian: http://bugs.python.org/su13866 .

EDIT # 2:

Tôi hiểu rằng cách mã hóa phổ biến nhất "" là "+", nhưng chỉ là một ghi chú, nó có thể chỉ là tôi, nhưng tôi thấy điều này hơi khó hiểu:

import urllib
print(urllib.urlencode({' ' : '+ '})

>>> '+=%2B+'

Không mã hóa. Cố gắng xác định từ góc độ thẩm mỹ những url của tôi chứa không gian sẽ trông như thế nào.
BC.

Xin chào, tôi cũng bối rối, Khi người dùng gửi biểu mẫu html, biểu mẫu mã hóa không gian như thế nào? với nhân vật nào? Là kết quả phụ thuộc vào trình duyệt?
GMsoF

1
URLEncoder.encode()phương thức trong Java cũng chuyển đổi nó +.
рüффп

Và sau đó, câu hỏi đặt ra là làm thế nào để xử lý mã hóa trong phần thân của một yêu cầu POST: "Loại nội dung: application / x-www-form-urlencoding" trong đó các tham số có dạng "a = b & c = d", nhưng hoàn toàn không có trong một URL, chỉ là phần thân của "tài liệu". Họ đã tạo ra một mớ hỗn độn thực sự từ vấn đề này, và thật khó để tìm ra câu trả lời dứt khoát.
fyngyrz

Perls uri_escape () coi họ là% 20
dùng

16

Một khoảng trắng chỉ có thể được mã hóa thành "+" trong phần truy vấn cặp khóa-giá trị loại nội dung "application / x-www-form-urlencoding" của URL. Theo tôi, đây là một tháng 5, không phải là PHẢI. Trong phần còn lại của URL, nó được mã hóa thành% 20.

Theo tôi, tốt hơn là luôn mã hóa khoảng trắng dưới dạng% 20, không phải là "+", ngay cả trong phần truy vấn của URL, bởi vì đó là đặc tả HTML (RFC-1866) đã chỉ định rằng các ký tự khoảng trắng nên được mã hóa thành " + Các cặp khóa-giá trị loại nội dung "trong" application / x-www-form-urlencoding "(xem đoạn 8.2.1. đoạn 1.)

Cách mã hóa dữ liệu biểu mẫu này cũng được đưa ra trong các thông số kỹ thuật HTML sau này. Ví dụ: tìm các đoạn có liên quan về ứng dụng / x-www-form-urlencoding trong Đặc tả HTML 4.01, v.v.

Dưới đây là một chuỗi mẫu trong URL nơi đặc tả HTML cho phép mã hóa không gian dưới dạng dấu cộng: " http://example.com/over/there?name=foo+bar ". Vì vậy, chỉ sau "?", Không gian có thể được thay thế bằng dấu cộng . Trong các trường hợp khác, khoảng trắng nên được mã hóa thành% 20. Nhưng vì thật khó để xác định chính xác bối cảnh, nên cách tốt nhất là không bao giờ mã hóa khoảng trắng là "+".

Tôi khuyên bạn nên mã hóa phần trăm tất cả các ký tự ngoại trừ "không được giám sát" được xác định trong RFC-3986, tr.2.3

unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"

Việc thực hiện phụ thuộc vào ngôn ngữ lập trình mà bạn đã chọn.

Nếu URL của bạn chứa các ký tự quốc gia, trước tiên hãy mã hóa chúng thành UTF-8 và sau đó mã hóa phần trăm kết quả.


1
Tại sao mọi người nên quan tâm đến đặc tả HTML nếu tài nguyên được yêu cầu không phải là HTML? Tôi đã thấy "+" trong một số API Web không phản hồi với HTML, ví dụ: bạn yêu cầu pdf. Tôi coi đó là sai khi họ không sử dụng "% 20".
Không thể tin được vào

@TheincredibleJan, tôi đồng ý với bạn. Đó là những gì câu trả lời của tôi là về.
Maxim Masiutin

1
@MaximMasiutin Khi câu trả lời của bạn nói "Đây là CÓ THỂ, không phải PHẢI", bạn đang đề cập đến thông số nào? Tôi đang vật lộn để tìm một thông số có thể là nó. Trong w3.org/TR/1999/REC-html401-19991224/interact/iêu sử dụng '+' (trong phần truy vấn) nằm trong phần 'phải' của thông số.
JosephH

2
@JosephH - cảm ơn bạn đã lưu ý. Đó là ý kiến ​​của tôi về MAY MẮN. Tôi đã chỉnh sửa bài viết. Điều tôi muốn nói là đặc tả HTML mà bạn qouted định nghĩa "+", nhưng trong ngữ cảnh URL, các quy tắc khác được áp dụng, cho phép không gian mã hóa là% 20.
Maxim Masiutin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.