Alat pengembang · URL encoder & decoder
Ditambah versus %20: riwayat penerapan/x-www-form-urlencoded
· Latar belakang
pengkodean url html-formulir http-standar
Formulir mengkodekan spasi sebagai + sedangkan standar URI menyatakan %20, dan alasannya bersifat historis. Postingan ini menelusuri konvensi dari bentuk awal HTML hingga definisi WHATWG saat ini dan menjelaskan mengapa konvensi tersebut tidak pernah hilang.
Ditambah versus %20—mengapa formulir dan URI mengkodekan spasi secara berbeda
HTML formulir yang dikirimkan sebagai GET menyandikan spasi sebagai tanda tambah dalam string kueri. Spasi yang sama menjadi %20 pada URL setelah RFC 3986. Keduanya benar karena mengikuti standar yang berbeda. Bidang formulir yang berisi spasi menjadi nama=nilai+dengan+spasi dalam pengkodean formulir tetapi %20 di RFC 3986. Perbedaan plus-persen-dua puluh menandai standar mana yang berlaku pada data Anda.
Pengkodean formulir menggunakan tanda plus untuk spasi sebagai konvensi historis dari definisi pengiriman formulir asli RFC 1866 (1995), HTML 2.0. GET meminta spasi yang dikodekan sebagai tanda plus, sisakan plus untuk literal + yang dikodekan sebagai %2B. Aturan ini hanya berlaku untuk application/x-www-form-urlencoded, bukan sintaks URI umum. Miliaran kerangka server menjadi bergantung pada konvensi ini. Pengujian keduanya menunjukkan perbedaan yang jelas: mode bentuk menghasilkan nilai plus; Mode URI menghasilkan %20. URL encoder & decoder menawarkan kedua mode untuk dibandingkan secara langsung.
Formulir HTML awal dan penyerahan GET — bagaimana pengkodean formulir ditentukan dan mengapa + dipilih
RFC 1866 (1995) mendefinisikan pengiriman formulir dengan spasi menjadi plus dan literal plus menjadi %2B. Ini hanya berlaku untuk application/x-www-form-urlencoded. RFC 3986 yang ditentukan %20 untuk sintaksis URI umum. Dua standar sengaja hidup berdampingan.
RFC 2396 memperjelas jaringan karakter dengan lebih ketat dibandingkan standar sebelumnya. Ini memformalkan karakter yang dicadangkan yang melayani struktur URI versus yang tidak dicadangkan sebagai data literal. Badan standar mengkodifikasi perilaku browser dan proxy seiring perkembangannya. RFC 3986 muncul kemudian tanpa mengubah perilaku pengkodean, hanya memperjelas notasi. Semua browser saat ini melakukan standarisasi pada pengkodean UTF-8. HTML formulir melalui tombol kirim kirim format lamaran/x-www-form-urlencoded dengan tanda tambah untuk spasi. Konstruksi manual URI menggunakan %20. Memahami kedua standar mencegah terjadinya kejutan integrasi.
RFC 1866 dan spesifikasi HTML yang lebih baru — tempat aturan ditulis dan perbedaannya dari sintaksis URI
WHATWG URL Standar menetapkan URLSearchParams.toString() menghasilkan keluaran application/x-www-form-urlencoded dengan tanda plus untuk spasi. URL persen konstruktor mengkodekan berikut RFC 3986. Browser bernavigasi ke URL dengan kode spasi %20; formulir dikirimkan sebagai GET mengkodekan plus. Alat-alat yang berbeda secara mendasar ini mempunyai tujuan yang berbeda pula. Enkode manualURIComponent memberikan gaya %20 untuk spasi—RFC 3986. Formulir dikirimkan ke URL kirim plus yang sama. Server yang mengurai pengiriman formulir mengharapkan plus; menerima %20 menyebabkan kegagalan parameter senyap.
Menguji keduanya mengungkapkan asumsi sisi server yang Anda andalkan. JavaScript URLSearchParams menyediakan penyembunyian pengkodean gaya bentuk yang aman ditambah kompleksitas. Buat URLSearchParams, tambahkan entri, panggil toString() untuk mendapatkan application/x-www-form-urlencoded dengan nilai tambah yang tepat. Alternatifnya, buat string kueri dengan encodeURIComponent; Anda mendapatkan RFC 3986 %20. Jangan pernah mencampurkan pendekatan. String kueri dengan manual plus dan encodeURIComponent menciptakan ambiguitas. Penerima tidak dapat membedakan apakah plus berarti spasi atau plus literal. Pendekatan standar ditangani secara konsisten.
Standar URL saat ini — aplikasi/x-www-form-urlencoded sebagai serialiser terpisah dengan aturannya sendiri
JSON API biasanya menolak plus sebagai spasi, mengharapkan %20 per RFC 3986. Klien yang mengirim plus gagal secara diam-diam: parameter hilang. Menguji API dengan kedua pengkodean akan mengungkapkan standar mana yang mereka terima. URLSearchParams di JavaScript menangani pengkodean formulir. URL encoder & decoder menghasilkan RFC 3986 %20.
Pengiriman formulir HTML secara otomatis menangani pengkodean. Kerangka server Anda menentukan aturan mana yang berlaku. Rails, Django, PHP semuanya memperlakukan plus sebagai spasi dalam data formulir yang diterima secara otomatis. Namun membuat string kueri secara manual untuk titik akhir yang sama sangatlah penting. Nilai tambah yang diunggah menciptakan ambiguitas. Kepatuhan spesifikasi dan perilaku server dunia nyata sedikit berbeda. Dokumentasikan standar yang diharapkan oleh titik akhir Anda. Uji kedua gaya pengkodean. Kode defensif menangani keduanya dengan baik.
Contoh praktis: bidang formulir yang sama terlihat sebagai string kueri dan sebagai isi permintaan — dengan + di satu tempat dan %20 di tempat lain
JavaScript URLSearchParams menerapkan pengkodean formulir: spasi menjadi plus, bukan %20. URLSearchParams baru({q: "hello world"}) menghasilkan "q=hello+world", bukan "q=hello%20world". Ini adalah aturan aplikasi/x-www-form-urlencoded historis yang dibangun secara khusus ke dalam JavaScript. Namun meneruskan string ini sebagai kueri mentah ke URL baru akan menjadikan plus sebagai plus; hanya URLSearchParams yang menerjemahkannya sebagai spasi. Konstruktor setia pada apa yang dilihatnya. Perbedaan tanda plus menyebabkan bug umum ketika fungsi pencampuran tidak tepat.
Konstruktor URL dan komponen encodeURI adalah alat yang berbeda. encodeURIComponent mengkodekan hampir semuanya kecuali huruf, angka, dan - _ yang tidak dicadangkan. ! ~ * ' ( ). Ini mengasumsikan tidak ada konteks. Konstruktor URL mem-parsing URL aktual dan menerapkan WHATWG aturan per komponen. encodeURIComponent mengubah "hello/world" menjadi "hello%2Fworld"; URL baru melihat garis miring sebagai pemisah jalur. Masukan yang sama, keluaran yang berbeda. Gunakan encodeURIComponent saat membuat URL dengan menggabungkan bagian-bagian. Gunakan konstruktor URLSearchParams atau URL untuk URL lengkap atau sebagian.
Mengapa hal ini tidak dapat diperbaiki — server dan klien selama puluhan tahun bergantung pada perilaku saat ini
Aturan pengkodean persen berevolusi dari RFC 1738 (1994) hingga RFC 2396 (1998) menjadi RFC 3986 (2005). Setiap generasi mengklarifikasi ambiguitas. RFC 1738 bersifat konservatif, memperlakukan karakter tidak aman karena web awal memiliki dukungan karakter yang terbatas. Penerapan distandarisasi pada UTF-8, penerapan menjadi konsisten. Standar selanjutnya melonggarkan pembatasan pada karakter yang terbukti aman di seluruh sistem. Konsensus modern: UTF-8 di mana pun. Badan standar sangat menjaga kompatibilitas ke belakang. Perbaikannya memerlukan koordinasi seluruh dunia—hal yang mustahil dilakukan setelah tiga dekade. Dua standar hidup berdampingan dengan sengaja.
Pengujian dengan plus dan %20 mengungkapkan asumsi server. Log server menunjukkan apa yang dikirim klien. Formulir menggunakan plus; URL manual menggunakan %20. Pilih berdasarkan konteks dan ikuti dokumentasi API.
Apa yang tidak tercakup dalam hal ini — badan multipart/form-data dan JSON
Menguji kedua pengkodean mengungkapkan perilaku server. Kirim a+b dua arah. Banyak server produksi mengharapkan pengkodean formulir; API yang lebih baru mengharapkan %20. Pilihan Anda bergantung pada ekspektasi penerima. URLSearchParams menangani pengkodean formulir; encodeURIComponent menangani pengkodean RFC.
Jangan pernah menggabungkan metode pengkodean. Nilai yang dikodekan dengan encodeURIComponent %2B lalu diteruskan ke URLSearchParams akan dikodekan ganda sebagai %252B. Penguraian kode sekali menghasilkan %2B, bukan plus. Karakter menjadi string persen-dua-enam literal, bukan tanda tambah. Periksa langkah-langkah perantara dalam proses pembangunan Anda. Pengkodean terjadi tepat satu kali per nilai saja. Dokumentasikan standar pengkodean yang digunakan saluran Anda. Uji dengan karakter khusus termasuk plus, spasi, ampersand.
Kesimpulan: dua standar, keduanya benar dalam konteksnya — bagaimana encoder & decoder URL memberi Anda bentuk RFC 3986, dengan %20 untuk spasi, sehingga Anda tahu mana yang sedang Anda lihat
Perpecahan plus-versus-dua puluh bukanlah bug yang perlu diperbaiki. Ini adalah artefak sejarah dari standar-standar yang memecahkan masalah-masalah tertentu secara berbeda. Perbaikannya memerlukan koordinasi seluruh dunia—yang tidak mungkin dilakukan setelah tiga puluh tahun. Badan standar tidak melanggar hukum secara surut. RFC 3986, aturan bentuk, konstruksi browser URL masing-masing memiliki standar dan alasan. RFC 1866 pengkodean formulir dan RFC 3986 URI pengkodean melayani lapisan yang berbeda. Encode dengan sengaja mengetahui standar Anda. Uji terhadap muatan yang realistis.
Pilih pengkodean berdasarkan konteks. Formulir menggunakan plus sesuai standar HTML. URI manual menggunakan %20 per RFC 3986. API menentukan apa yang diharapkan; ikuti dokumentasi atau uji keduanya. URL encoder & decoder menampilkan RFC 3986. Butuh pengkodean formulir? URLSearchParams melakukan itu. Alat tidak mencampur pengkodean; standar pemahaman mencegah kejutan. Ketidakkonsistenan pengkodean antar lapisan menyebabkan hilangnya parameter, pemotongan, dan kerusakan data secara halus. Kedua standar tersebut benar dalam domainnya. Terapkan dengan sengaja dan dokumentasikan.