Adres URL kodujący znak spacji: + lub% 20?

722

Kiedy spacja w adresie URL jest zakodowana +, a kiedy jest zakodowana %20?

PNE.
źródło
2
To pytanie byłoby bardziej przydatne jako kilka pytań specyficznych dla języka, prawda?
squarecandy
2
Możliwy duplikat Kiedy kodować spację na plus (+) lub% 20?
użytkownik
3
@user pytanie, do którego prowadzi link, zostało zadane później, co czyni go duplikatem, nie tym.
Warlike Chimpanzee

Odpowiedzi:

425

Z Wikipedii (wyróżnienie i link dodane):

Po przesłaniu danych, które zostały wprowadzone do formularzy HTML, nazwy i wartości pól formularza są kodowane i wysyłane do serwera w wiadomości żądania HTTP przy użyciu metody GET lub POST lub, historycznie, za pośrednictwem poczty elektronicznej. Domyślnie stosowane kodowanie opiera się na bardzo wczesnej wersji ogólnych reguł kodowania procentowego URI, z kilkoma modyfikacjami, takimi jak normalizacja nowej linii i zamiana spacji na „+” zamiast na „% 20”. Dane MIME zakodowane w ten sposób to application / x-www-form-urlencoded i są obecnie zdefiniowane (wciąż w bardzo nieaktualny sposób) w specyfikacjach HTML i XForms.

Tak więc rzeczywiste kodowanie procentowe wykorzystuje, %20podczas gdy dane formularza w adresach URL są w zmodyfikowanej formie, która wykorzystuje +. Więc najprawdopodobniej zobaczysz tylko +w adresach URL w ciągu zapytania po ?.

Joey
źródło
2
Więc + kodowanie byłoby technicznie kodowaniem wieloczęściowym / formularzem danych, podczas gdy kodowanie procentowe jest zakodowane w formacie application / x-www-form-urlencod?
BC.
17
@BC: nie - multipart/form-dataużywa kodowania MIME; application/x-www-form-urlencodedużywa +i odpowiednio koduje użycie identyfikatorów URI %20.
McDowell
8
„Więc najprawdopodobniej zobaczysz + w adresach URL w ciągu zapytania po?” To mało powiedziane. Nigdy nie powinieneś widzieć „+” w części ścieżki adresu URL, ponieważ nie spełni on oczekiwań (spacja).
Adam Gent
34
Więc w zasadzie: celem przesyłania GET jest http://www.bing.com/search?q=hello+worldi zasób ze spacją w nazwiehttp://camera.phor.net/cameralife/folders/2012/2012-06%20Pool%20party/
William Entriken
8
Pamiętaj, że do linków e-mail potrzebujesz% 20, a nie + po. Na przykład mailto:[email protected]?subject=I%20need%20help. Jeśli próbowałeś tego za pomocą +, wiadomość e-mail otworzy się za pomocą + es zamiast spacji.
Sygmoral,
287

To zamieszanie wynika z tego, że adresy URL są nadal „zepsute” do dziś.

Weźmy na przykład „ http://www.google.com ”. To jest adres URL. Adres URL to jednolity lokalizator zasobów i tak naprawdę jest wskaźnikiem do strony internetowej (w większości przypadków). Adresy URL faktycznie mają bardzo dobrze zdefiniowaną strukturę od pierwszej specyfikacji w 1994 roku.

Możemy wyodrębnić szczegółowe informacje o adresie URL „ http://www.google.com ”:

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

Jeśli spojrzymy na bardziej złożony adres URL, taki jak:

https: // bob: [email protected]: 8080 / plik; p = 1? q = 2 # trzeci

możemy wyodrębnić następujące informacje:

+-------------------+---------------------+
|        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:[email protected]:8080/file;p=1?q=2#third
\___/   \_/ \___/ \______________/ \__/\_______/ \_/ \___/
  |      |    |          |          |      | \_/  |    |
Scheme User Password    Host       Port  Path |   | Fragment
        \_____________________________/       | Query
                       |               Path parameter
                   Authority

Znaki zastrzeżone są różne dla każdej części.

W przypadku adresów URL HTTP spacja w części fragmentu ścieżki musi być zakodowana na „% 20” (nie, absolutnie nie na „+”), podczas gdy znak „+” w części fragmentu ścieżki może pozostać niezakodowany.

Teraz w części zapytania spacje mogą być kodowane do „+” (dla kompatybilności wstecznej: nie próbuj jej szukać w standardzie URI) lub „% 20”, podczas gdy znak „+” (z powodu tej niejednoznaczności ) należy zmienić na „% 2B”.

Oznacza to, że ciąg „niebieski + jasnoniebieski” musi być inaczej zakodowany w części ścieżki i zapytania:

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

Stąd można wywnioskować, że kodowanie w pełni skonstruowanego adresu URL jest niemożliwe bez świadomości składniowej struktury adresu URL.

Sprowadza się to do:

Powinieneś to zrobić %20przed ?i +po.

Źródło

Matas Vaitkevicius
źródło
>> powinieneś mieć% 20 przed? i + po Przepraszam za głupie pytanie. Wiem trochę, że parametr hashtag jest używany po „?” parametr znaku zapytania. Chociaż jest jakoś inaczej, ponieważ użycie „#” nie powoduje ponownego załadowania strony. Ale próbowałem użyć znaku% 20 i + po hasztagu „#” i wydaje się, że nie działa. Którego należy użyć po „#”?
Philcyb,
@Philcyb Możesz przeczytać to en.wikipedia.org/wiki/Percent-encoding
Matas Vaitkevicius
Czy część zapytania ma rzeczywiście „oficjalny” standard? Myślałem w zasadzie, że ta część jest specyficzna dla aplikacji. 99,99% aplikacji korzysta key1=value1&key1=value2z kodowania kluczy i wartości według dowolnych reguł, encodeURIComponentale AFAIK zawartość części zapytania jest całkowicie w 100% zależna od aplikacji. Poza tym chodzi tylko o to, #że nie ma oficjalnego kodowania.
gman
Zduplikowana odpowiedź na zduplikowane pytanie! Ale hmm, ok, zrezygnowałem z obu.
Vladimir Vukanac
2
To oznakowanie komponentu ASCII jest niesamowite.
jsejcksn
25

Polecam %20.

Czy je kodujesz?

Nie jest to jednak zbyt spójne we wszystkich językach. Jeśli się nie mylę, w PHP urlencode()traktuje się spacje jako, +podczas gdy Python urlencode()traktuje je jako %20.

EDYTOWAĆ:

Wygląda na to, że się mylę. Python urlencode()(przynajmniej w wersji 2.7.2) używa quote_plus()zamiast, quote()a zatem koduje spacje jako „+”. Wydaje się również, że zaleceniem W3C jest „+” zgodnie z tutaj: http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1

W rzeczywistości możesz śledzić tę interesującą debatę na temat własnego narzędzia do śledzenia problemów Pythona na temat tego, jak używać do kodowania spacji: http://bugs.python.org/issue13866 .

EDYCJA 2:

Rozumiem, że najczęstszym sposobem kodowania „” jest „+”, ale tylko uwaga, może to być tylko ja, ale wydaje mi się to nieco mylące:

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

>>> '+=%2B+'
Rui Vieira
źródło
Nie zakodowane na stałe. Próbuję ustalić z estetycznego punktu widzenia, jak będą wyglądać moje adresy URL zawierające spacje.
BC.
Cześć, ja też jestem zdezorientowany. Kiedy użytkownik przesyła formularz HTML, w jaki sposób formularz koduje spację? z jaką postacią? Czy wynik zależy od przeglądarki?
GMsoF,
1
A URLEncoder.encode()metoda w Javie zamienia go w +jako dobrze.
рüффп
A potem pojawia się pytanie, jak traktować kodowanie w treści żądania POST: „Content-Type: application / x-www-form-urlencoded”, gdzie parametry mają postać „a = b & c = d”, ale wcale nie są w adresie URL, tylko w treści „dokumentu”. Zrobili prawdziwy bałagan z tego problemu i trudno jest znaleźć ostateczne odpowiedzi.
fyngyrz
Perls uri_escape () traktuje je jako% 20
someuser
16

Spacja może być zakodowana tylko do „+” w części zapytania URL-a par „klucz / wartość typu„ application / x-www-form-urlencoded ” Moim zdaniem jest to MAJO, a NIE MUSI. W pozostałych adresach URL jest zakodowany jako% 20.

Moim zdaniem lepiej zawsze kodować spacje jako% 20, a nie jako „+”, nawet w części adresu URL zapytania, ponieważ to specyfikacja HTML (RFC-1866) określa, że ​​znaki spacji powinny być kodowane jako „ + „in” application / x-www-form-urlencoded ”pary klucz-wartość typu treści (patrz ust. 8.2.1. akapit 1)

Ten sposób kodowania danych formularza podano również w późniejszych specyfikacjach HTML. Na przykład poszukaj odpowiednich akapitów na temat application / x-www-form-urlencoded w specyfikacji HTML 4.01 i tak dalej.

Oto przykładowy ciąg w adresie URL, w którym specyfikacja HTML pozwala na kodowanie spacji jako plusów: „ http://example.com/over/there?name=foo+bar ”. Tak więc, tylko po „?” Spacje można zastąpić plusami . W innych przypadkach spacje powinny być kodowane do% 20. Ponieważ jednak trudno jest poprawnie określić kontekst, najlepszą praktyką jest, aby nigdy nie kodować spacji jako „+”.

Poleciłbym procentowe kodowanie wszystkich znaków oprócz „niezarezerwowanych” zdefiniowanych w RFC-3986, str. 2.3

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

Implementacja zależy od wybranego języka programowania.

Jeśli twój adres URL zawiera znaki narodowe, najpierw zakoduj je w UTF-8, a następnie procentowo koduj wynik.

Maxim Masiutin
źródło
1
Dlaczego ktoś miałby przejmować się specyfikacją HTML, jeśli żądany zasób nie jest HTML? Widziałem „+” w niektórych interfejsach API sieci Web, które nie odpowiadają HTML, np. Prosisz o pdf. Uważam za niewłaściwe, że nie używają „% 20”.
Niesamowity
@TheincredibleJan, zgadzam się z tobą. Na tym polega moja odpowiedź.
Maxim Masiutin
1
@MaximMasiutin Kiedy Twoja odpowiedź brzmi „To MAJ, NIE MUSI”, o której specyfikacji masz na myśli? Usiłuję znaleźć specyfikację, która ma to jako maj. W w3.org/TR/1999/REC-html401-19991224/interact/… użycie „+” (w sekcji zapytania) znajduje się w sekcji „must” specyfikacji.
JosephH
2
@JosephH - dziękuję za notatkę. To moja osobista opinia o MAJU. Zredagowałem post. Chodziło mi o to, że specyfikacja HTML, którą wypowiedziałeś, definiuje „+”, ale w kontekście adresu URL obowiązują inne reguły, które zezwalają na kodowanie spacji jako% 20.
Maxim Masiutin