Alat pembangun · URL pengekod & penyahkod
Ditambah berbanding %20: sejarah aplikasi/x-www-form-urlencoded
· Latar belakang
pengekodan url html-borang http-standard
Borang mengekod ruang sebagai + manakala standard URI menyatakan %20 dan sebabnya adalah sejarah. Siaran ini mengesan konvensyen daripada borang HTML awal hingga takrifan WHATWG hari ini dan menerangkan sebab ia tidak pernah hilang.
Ditambah berbanding %20—mengapa borang dan URI mengekod ruang secara berbeza
HTML borang diserahkan sebagai GET mengekod ruang sebagai tanda tambah dalam rentetan pertanyaan. Ruang yang sama menjadi %20 dalam URL berikutan RFC 3986. Kedua-duanya betul kerana mengikut piawaian yang berbeza. Medan borang yang mengandungi ruang menjadi nama=nilai+dengan+ruang dalam pengekodan borang tetapi %20 dalam RFC 3986. Perbezaan tambah-peratus-dua puluh menandakan piawaian yang digunakan untuk data anda.
Pengekodan borang menggunakan tambah untuk ruang sebagai konvensyen sejarah daripada definisi penyerahan borang asal RFC 1866 (1995), HTML 2.0. GET meminta ruang yang dikodkan sebagai tanda tambah, menempah tambah untuk literal + dikodkan sebagai %2B. Peraturan ini digunakan sahaja pada aplikasi/x-www-form-urlencoded, bukan umum URI sintaks. Berbilion rangka kerja pelayan menjadi bergantung pada konvensyen ini. Menguji kedua-duanya menunjukkan perbezaan yang jelas: mod bentuk menghasilkan tambah; Mod URI menghasilkan %20. URL pengekod & penyahkod menawarkan kedua-dua mod untuk dibandingkan secara langsung.
Borang HTML dan penyerahan GET awal — cara pengekodan borang ditakrifkan dan sebab + dipilih
RFC 1866 (1995) mentakrifkan penyerahan borang di mana ruang menjadi tambah dan tambah literal menjadi %2B. Ini digunakan sahaja pada aplikasi/x-www-form-urlencoded. RFC 3986 ditentukan %20 untuk sintaks URI umum. Dua piawaian wujud bersama dengan sengaja.
RFC 2396 set aksara yang diperjelaskan dengan lebih ketat daripada piawaian terdahulu. Ia memformalkan aksara tersimpan yang menyajikan struktur URI berbanding tidak terpelihara sebagai data literal. Badan piawai mengkodkan tingkah laku pelayar dan proksi semasa ia berkembang. RFC 3986 datang kemudian tanpa mengubah tingkah laku pengekodan, sahaja menjelaskan notasi. Semua pelayar semasa menyeragamkan pada pengekodan UTF-8. HTML borang melalui butang hantar hantar permohonan/x-www-form-urlencoded format dengan tambah untuk ruang. Pembinaan URI manual menggunakan %20. Memahami kedua-dua piawaian menghalang kejutan penyepaduan.
RFC 1866 dan kemudian HTML spesifikasi — tempat peraturan ditulis dan cara ia menyimpang daripada sintaks URI
WHATWG URL Standard menentukan URLSearchParams.toString() menghasilkan aplikasi/x-www-form-urlencoded output dengan tanda tambah untuk ruang. URL peratus pembina mengekod mengikut RFC 3986. Pelayar menavigasi ke URL dengan pengekodan ruang %20; borang diserahkan sebagai GET mengekod tambah. Alat yang pada asasnya berbeza ini mempunyai tujuan yang berbeza. EncodeURIComponent manual memberikan %20 untuk ruang—RFC 3986 gaya. Borang diserahkan kepada URL hantar tambah yang sama. Penyerahan borang penghuraian pelayan mengharapkan tambah; menerima %20 menyebabkan kegagalan parameter senyap.
Menguji kedua-duanya mendedahkan andaian sebelah pelayan yang anda bergantung kepada. JavaScript URLSearchParams menyediakan penyembunyian pengekodan gaya bentuk yang selamat serta kerumitan. Bina URLSearchParams, tambah entri, panggil keString() untuk mendapatkan application/x-www-form-urlencoded dengan tambah yang betul. Secara alternatif bina rentetan pertanyaan dengan encodeURIComponent; anda mendapat RFC 3986 %20. Jangan sekali-kali mencampurkan pendekatan. Rentetan pertanyaan dengan tambah manual dan encodeURIComponent mencipta kekaburan. Penerima tidak dapat membezakan jika tambah bermakna ruang atau tambah literal. Pendekatan standard mengendalikan secara konsisten.
URL Standard hari ini — aplikasi/x-www-form-urlencoded sebagai penyeri bersiri berasingan dengan peraturannya sendiri
JSON API biasanya menolak tambah sebagai ruang, menjangkakan %20 setiap RFC 3986. Pelanggan menghantar tambah gagal secara senyap: parameter lenyap. Menguji API dengan kedua-dua pengekodan mendedahkan standard yang mereka terima. URLSearchParams dalam JavaScript mengendalikan pengekodan borang. URL pengekod & penyahkod menghasilkan RFC 3986 %20.
HTML penyerahan borang secara automatik mengendalikan pengekodan. Rangka kerja pelayan anda menentukan peraturan yang digunakan. Rails, Django, PHP semuanya menganggap tambah sebagai ruang dalam data borang yang diterima secara automatik. Tetapi membina rentetan pertanyaan secara manual untuk titik akhir yang sama sangat penting. Tambahan yang dimuat naik menimbulkan kesamaran. Pematuhan spesifikasi dan tingkah laku pelayan dunia nyata berbeza sedikit. Dokumenkan piawaian yang dijangkakan oleh titik akhir anda. Uji kedua-dua gaya pengekodan. Kod pertahanan mengendalikan kedua-duanya dengan anggun.
Contoh berfungsi: medan borang yang sama dilihat sebagai rentetan pertanyaan dan sebagai badan permintaan — dengan + di satu tempat dan %20 di tempat lain
JavaScript URLSearchParams menggunakan pengekodan borang: ruang menjadi tambah, bukan %20. URLSearchParams baharu({q: "hello world"}) menghasilkan "q=hello+world", bukan "q=hello%20world". Ini ialah peraturan application/x-www-form-urlencoded sejarah yang terbina dalam JavaScript secara khusus. Tetapi menghantar rentetan ini sebagai pertanyaan mentah kepada URL baharu kekal tambah sebagai tambah; sahaja URLSearchParams yang menyahkodnya sebagai ruang. Pembina setia dengan apa yang dilihatnya. Perbezaan tanda tambah menyebabkan pepijat biasa apabila mencampurkan fungsi secara tidak betul.
URL pembina dan encodeURIComponent ialah alat yang berbeza. encodeURIComponent mengekod hampir semua perkara kecuali huruf, digit dan -_ . ! ~ * ' ( ). Ia tidak menganggap konteks. URL pembina menghuraikan URL sebenar dan menggunakan peraturan WHATWG bagi setiap komponen. encodeURIComponent menukar "hello/world" kepada "hello%2Fworld"; URL baharu melihat garis miring sebagai pemisah laluan. Input yang sama, output yang berbeza. Gunakan encodeURIComponent apabila membina URL dengan menggabungkan kepingan. Gunakan URLSearchParams atau pembina URL untuk URL lengkap atau separa.
Mengapa ia tidak boleh diperbaiki — berdekad-dekad pelayan dan pelanggan yang bergantung pada tingkah laku semasa
Percent-encoding rules evolved daripada RFC 1738 (1994) through RFC 2396 (1998) kepada RFC 3986 (2005). Setiap generasi menjelaskan kekaburan. RFC 1738 adalah konservatif, memperlakukan aksara tidak selamat kerana web awal mempunyai sokongan aksara yang terhad. Penggunaan diseragamkan pada UTF-8, pelaksanaan menjadi konsisten. Piawaian kemudian melonggarkan sekatan ke atas aksara yang terbukti selamat merentas sistem. Konsensus moden: UTF-8 di mana-mana sahaja. Badan piawai mengekalkan keserasian ke belakang dengan sengit. Pembetulan memerlukan penyelarasan di seluruh dunia—tidak mungkin selepas tiga dekad. Dua piawaian wujud bersama dengan sengaja.
Ujian dengan tambah dan %20 mendedahkan andaian pelayan. Log pelayan menunjukkan perkara yang dihantar oleh pelanggan. Borang menggunakan tambah; URL manual menggunakan %20. Pilih mengikut konteks dan ikuti dokumentasi API.
Perkara yang tidak dilindungi ini — badan berbilang/form-data dan JSON
Menguji kedua-dua pengekodan mendedahkan tingkah laku pelayan. Hantar a+b kedua-dua arah. Banyak pelayan pengeluaran mengharapkan pengekodan borang; API yang lebih baharu menjangkakan %20. Pilihan anda bergantung pada jangkaan penerima. URLSearchParams mengendalikan pengekodan borang; encodeURIComponent mengendalikan pengekodan RFC.
Jangan sekali-kali menggabungkan kaedah pengekodan. Nilai yang dikodkan dengan encodeURIComponent %2B kemudian dihantar ke URLSearchParams akan dikodkan dua kali sebagai %252B. Penyahkodan sekali menghasilkan %2B bukannya tambah. Aksara menjadi peratus literal-dua-enam rentetan daripada tanda tambah. Semak langkah perantaraan dalam proses binaan anda. Pengekodan berlaku tepat sekali bagi setiap nilai sahaja. Dokumenkan standard pengekodan yang digunakan oleh saluran paip anda. Uji dengan aksara khas termasuk tambah, ruang, ampersand.
Bawa pulang: dua standard, kedua-duanya betul dalam konteksnya — cara pengekod & penyahkod URL memberi anda borang RFC 3986, dengan %20 untuk ruang, jadi anda tahu yang mana satu yang anda lihat
Perpecahan tambah-berbanding-dua puluh bukanlah pepijat untuk diperbaiki. Ia adalah artifak sejarah piawaian yang menyelesaikan masalah yang berbeza secara berbeza. Pembetulan memerlukan penyelarasan di seluruh dunia—tidak mungkin selepas tiga puluh tahun. Badan piawai tidak memecahkan web secara retroaktif. RFC 3986, peraturan borang, pelayar URL pembinaan masing-masing mempunyai standard dan sebab. RFC 1866 pengekodan borang dan RFC 3986 URI pengekodan menyediakan lapisan yang berbeza. Encode dengan sengaja mengetahui standard anda. Uji terhadap muatan yang realistik.
Pilih pengekodan mengikut konteks. Borang menggunakan tambah mengikut piawaian HTML. URI manual menggunakan %20 setiap RFC 3986. API menentukan yang diharapkan; ikut dokumentasi atau uji kedua-duanya. URL pengekod & penyahkod menunjukkan RFC 3986. Perlukan pengekodan borang? URLSearchParams melakukannya. Alat tidak mencampurkan pengekodan; pemahaman standard menghalang kejutan. Ketidakkonsistenan pengekodan antara lapisan menyebabkan kehilangan parameter halus, pemotongan, kerosakan data. Kedua-dua piawaian adalah betul dalam domain mereka. Memohon dengan sengaja dan dokumen.