URL yang menyandikan karakter spasi: + atau% 20?

723

Kapan ruang dalam URL disandikan +, dan kapan ruang itu disandikan %20?

SM.
sumber
2
Pertanyaan ini akan lebih membantu karena beberapa pertanyaan khusus bahasa, bukan?
squarecandy
2
Kemungkinan rangkap dari Kapan untuk menyandikan ruang ke plus (+) atau% 20?
pengguna
3
@menggunakan pertanyaan yang Anda tautkan ditanyakan kemudian, menjadikannya sebagai penipuan, bukan yang ini.
Simpanse Warlike

Jawaban:

425

Dari Wikipedia (penekanan dan tautan ditambahkan):

Ketika data yang telah dimasukkan ke dalam formulir HTML dikirimkan, nama dan nilai bidang formulir dikodekan dan dikirim ke server dalam pesan permintaan HTTP menggunakan metode GET atau POST, atau, secara historis, melalui email. Pengkodean yang digunakan secara default didasarkan pada versi yang paling awal dari aturan pengkodean persen URI umum, dengan sejumlah modifikasi seperti normalisasi baris baru dan penggantian spasi dengan "+" alih-alih "% 20". Jenis data MIME yang disandikan dengan cara ini adalah application / x-www-form-urlencoded, dan saat ini didefinisikan (masih dalam cara yang sangat ketinggalan zaman) dalam spesifikasi HTML dan XForms.

Jadi, persentase pengkodean yang sebenarnya menggunakan %20data formulir di URL adalah dalam bentuk yang dimodifikasi yang menggunakan +. Jadi, Anda kemungkinan besar hanya melihat +di URL dalam string kueri setelah ?.

Joey
sumber
2
Jadi + encoding secara teknis akan menjadi multipart / form-data encoding, sedangkan persen encoding adalah application / x-www-form-urlencoded?
BC.
17
@BC: tidak - multipart/form-datamenggunakan penyandian MIME; application/x-www-form-urlencodedmenggunakan +dan menggunakan URI yang disandikan dengan benar %20.
McDowell
8
"Jadi, Anda kemungkinan besar hanya melihat + dalam URL di string kueri setelah?" Adalah sebuah pernyataan. Anda seharusnya tidak pernah melihat "+" di bagian jalur URL karena itu tidak akan melakukan apa yang Anda harapkan (spasi).
Adam Gent
34
Jadi pada dasarnya: Target pengajuan GET adalah http://www.bing.com/search?q=hello+worlddan sumber daya dengan ruang dalam namahttp://camera.phor.net/cameralife/folders/2012/2012-06%20Pool%20party/
William Entriken
8
Perhatikan bahwa untuk tautan email, Anda perlu% 20 dan bukan + setelah? Sebagai contoh mailto:[email protected]?subject=I%20need%20help,. Jika Anda mencobanya dengan +, email akan terbuka dengan + bukan spasi.
Sygmoral
288

Kebingungan ini karena URL masih 'rusak' hingga hari ini.

Ambil " http://www.google.com " misalnya. Ini adalah URL. URL adalah Uniform Resource Locator dan benar-benar penunjuk ke halaman web (dalam kebanyakan kasus). URL sebenarnya memiliki struktur yang didefinisikan dengan sangat baik sejak spesifikasi pertama pada tahun 1994.

Kami dapat mengekstrak informasi terperinci tentang URL " http://www.google.com ":

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

Jika kita melihat URL yang lebih kompleks seperti:

" https: // bob: [email protected]: 8080 / file; p = 1? q = 2 # third "

kami dapat mengekstrak informasi berikut:

+-------------------+---------------------+
|        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

Karakter yang dipesan berbeda untuk setiap bagian.

Untuk HTTP URL, spasi di bagian fragmen path harus dikodekan ke "% 20" (tidak, sama sekali bukan "+"), sedangkan karakter "+" di bagian fragmen path dapat dibiarkan tidak disandi.

Sekarang di bagian permintaan, spasi dapat dikodekan ke "+" (untuk kompatibilitas mundur: jangan mencoba mencarinya dalam standar URI) atau "% 20" sedangkan karakter "+" (sebagai akibat dari ambiguitas ini ) harus diloloskan ke "% 2B".

Ini berarti bahwa string "biru + biru muda" harus dikodekan secara berbeda di jalur dan bagian permintaan:

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

Dari sana Anda dapat menyimpulkan bahwa pengkodean URL yang dibangun sepenuhnya tidak mungkin dilakukan tanpa kesadaran sintaksis terhadap struktur URL.

Ini bermuara pada:

Anda harus memiliki %20sebelum ?dan +sesudah.

Sumber

Matas Vaitkevicius
sumber
>> Anda harus memiliki% 20 sebelum? dan + setelah Maaf untuk pertanyaan konyol. Saya tahu entah bagaimana parameter hashtag digunakan setelah "?" parameter tanda tanya. Meskipun agak berbeda karena menggunakan "#" tidak memuat ulang halaman. Tapi saya sudah mencoba menggunakan tanda% 20 dan + setelah tagar "#", dan sepertinya tidak berfungsi. Yang mana yang perlu digunakan setelah "#"?
Philcyb
@ Philcyb Anda mungkin ingin membaca ini en.wikipedia.org/wiki/Percent-encoding
Matas Vaitkevicius
Apakah bagian permintaan sebenarnya memiliki standar "resmi"? Saya pikir pada dasarnya bagian itu adalah aplikasi spesifik. 99,99% aplikasi menggunakan key1=value1&key1=value2mana kunci dan nilai dikodekan dengan aturan apa pun yang encodeURIComponentmengikuti tetapi AFAIK konten bagian permintaan sepenuhnya 100% hingga aplikasi. Selain itu hanya pergi ke yang pertama #tidak ada pengkodean resmi.
gman
Jawaban duplikat untuk pertanyaan duplikat! Tapi hmm, ok, saya menyerah pada keduanya.
Vladimir Vukanac
3
Pelabelan komponen ASCII itu epik.
jsejcksn
25

Saya akan merekomendasikan %20.

Apakah Anda mengkodekan mereka?

Ini tidak terlalu konsisten di semua bahasa. Jika saya tidak salah, dalam PHP urlencode()memperlakukan spasi sebagai +sedangkan Python urlencode()memperlakukannya sebagai %20.

EDIT:

Sepertinya saya salah. Python urlencode()(setidaknya dalam 2.7.2) menggunakan quote_plus()alih-alih quote()dan dengan demikian mengkodekan spasi sebagai "+". Tampaknya juga bahwa rekomendasi W3C adalah "+" seperti di sini: http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1

Dan faktanya, Anda dapat mengikuti debat menarik tentang pelacak masalah Python sendiri tentang apa yang harus digunakan untuk menyandikan spasi: http://bugs.python.org/issue13866 .

EDIT # 2:

Saya mengerti bahwa cara paling umum untuk menyandikan "" adalah sebagai "+", tetapi hanya sebuah catatan, mungkin hanya saya, tetapi saya merasa ini agak membingungkan:

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

>>> '+=%2B+'
Rui Vieira
sumber
Bukan hardcoding. Mencoba menentukan dari perspektif estetika seperti apa url saya yang berisi ruang akan terlihat.
BC.
Hai, saya juga bingung, Ketika pengguna mengirimkan formulir html, bagaimana formulir menyandikan spasi? dengan karakter yang mana? Apakah hasilnya tergantung pada browser?
GMsoF
1
Dan URLEncoder.encode()metode di Jawa mengubahnya +juga.
рüффп
Dan kemudian muncul pertanyaan tentang bagaimana memperlakukan pengkodean dalam isi permintaan POST: "Content-Type: application / x-www-form-urlencoded" di mana parameternya dalam bentuk "a = b & c = d", tetapi sama sekali tidak ada dalam URL, hanya isi "dokumen". Mereka benar-benar membuat kekacauan dari masalah ini, dan sangat sulit untuk menemukan jawaban yang pasti.
fyngyrz
Perls uri_escape () memperlakukan mereka sebagai% 20
someuser
16

Ruang hanya dapat disandikan ke "+" di bagian "permintaan-jenis-tipe-nilai-pasangan" dari aplikasi / x-www-form-urlencoded "dari suatu URL. Menurut pendapat saya, ini MUNGKIN, bukan HARUS. Di sisa URL, itu dikodekan sebagai% 20.

Menurut pendapat saya, lebih baik untuk selalu menyandikan spasi sebagai% 20, bukan sebagai "+", bahkan di bagian permintaan URL, karena itu adalah spesifikasi HTML (RFC-1866) yang menentukan bahwa karakter spasi harus dikodekan sebagai " + "in" application / x-www-form-urlencoded "pasangan nilai kunci tipe konten (lihat paragraf 8.2.1. subparagraf 1.)

Cara pengkodean data formulir ini juga diberikan dalam spesifikasi HTML yang lebih baru. Misalnya, cari paragraf yang relevan tentang aplikasi / x-www-form-urlencoded di Spesifikasi HTML 4.01, dan seterusnya.

Berikut ini contoh string dalam URL di mana spesifikasi HTML memungkinkan ruang penyandian sebagai nilai tambah: " http://example.com/over/there?name=foo+bar ". Jadi, hanya setelah "?", Spasi dapat diganti dengan plus . Dalam kasus lain, spasi harus dikodekan ke% 20. Tapi karena sulit untuk menentukan konteks dengan benar, itu praktik terbaik untuk tidak pernah menyandikan spasi sebagai "+".

Saya akan merekomendasikan untuk meng-encode semua karakter kecuali "unreserved" yang didefinisikan dalam RFC-3986, hal.2.3

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

Implementasinya tergantung pada bahasa pemrograman yang Anda pilih.

Jika URL Anda berisi karakter nasional, pertama-tama kodekan untuk UTF-8 dan kemudian persen-kodekan hasilnya.

Maxim Masiutin
sumber
1
Mengapa orang harus peduli tentang spesifikasi HTML jika sumber yang diminta bukan HTML? Saya telah melihat "+" di beberapa API Web yang tidak merespons dengan HTML misalnya Anda meminta pdf. Saya menganggap salah bahwa mereka tidak menggunakan "% 20".
Luar biasa
@TheincredibleJan, saya setuju dengan Anda. Itulah jawaban saya.
Maxim Masiutin
1
@ MaximMasiutin Ketika jawaban Anda mengatakan "Ini MUNGKIN, bukan HARUS", spek apa yang Anda maksud? Saya berjuang untuk menemukan spesifikasi yang memilikinya. Di w3.org/TR/1999/REC-html401-19991224/interact/… menggunakan '+' (di bagian permintaan) ada di dalam bagian 'harus' dari spesifikasi.
JosephH
2
@ JosephephH - terima kasih atas catatan Anda. Ini adalah pendapat persuasif saya tentang MEI. Saya telah mengedit posting. Apa yang saya maksudkan adalah spesifikasi HTML yang Anda tentukan mendefinisikan "+", tetapi dalam konteks URL, aturan lain berlaku, yang mengizinkan ruang penyandian sebagai% 20 juga.
Maxim Masiutin