Pengode / pendekode URL
Persen-kodekan dan dekode URL, pilih cakupan komponen atau URL penuh, dan lihat URL terurai menjadi bagian-bagiannya.
Untuk satu nilai seperti satu parameter kueri. Meng-escape / ? : @ & = + pula, karena di sana mereka data ketimbang struktur.
Keluaran akan muncul di sini
Untuk apa persen-pengodean
URL hanya diizinkan mengandung sekumpulan kecil karakter: huruf A–Z dan a–z, digit, segelintir tanda seperti - . _ ~, dan sekumpulan karakter tercadang yang memberi alamat bentuknya — / ? # & = : @ dan beberapa lagi. Apa pun yang lain, dari spasi hingga kata Ibrani hingga emoji, harus direpresentasikan secara tak langsung. Persen-pengodean adalah representasi itu: karakternya diubah ke bita UTF-8-nya dan tiap bita ditulis sebagai tanda persen diikuti dua digit heksadesimal. Spasi menjadi %20, dan א menjadi %D7%90.
Karakter tercadang adalah kasus yang menarik. Mereka sah dalam URL, tetapi mereka berarti sesuatu yang struktural: ? memulai kueri, & memisahkan parameter, = membelah kunci dari nilainya. Ketika salah satu karakter itu adalah bagian dari data Anda ketimbang bagian dari struktur, ia harus dikodekan — jika tidak pengurai di ujung lain akan membacanya sebagai tanda baca dan membelah nilai Anda di tempat yang salah.
Komponen atau URL penuh — perbedaan yang merusak tautan
Ini adalah sumber tunggal paling umum bug URL, dan itu sebabnya alat ini meminta Anda memilih cakupan ketimbang menebak.
- Cakupan komponen meng-escape pembatas pula: / ? : @ & = + $ , dan #. Pakai untuk satu potong data — istilah pencarian, target pengalihan, token — yang ditaruh di dalam URL yang lebih besar.
- Cakupan URL penuh membiarkan pembatas itu dan meng-escape hanya yang benar-benar ilegal, seperti spasi dan teks non-ASCII. Pakai ketika Anda punya alamat lengkap yang sudah terstruktur dengan benar dan sekadar perlu dibersihkan.
Salah di arah mana pun dan sesuatu rusak. Kodekan seluruh URL dalam cakupan komponen dan setiap garis miring dan tanda tanya berubah menjadi %2F dan %3F, menghasilkan satu string panjang yang tak terpakai. Kodekan satu nilai dalam cakupan URL penuh dan ampersand di dalamnya bertahan sebagai pembatas, jadi pencarian untuk "cats & dogs" diam-diam menjadi dua parameter dan separuh kedua nilai Anda lenyap.
// The value contains a delimiter, so it must be escaped:
const q = 'cats & dogs'
`/search?q=${encodeURIComponent(q)}` // /search?q=cats%20%26%20dogs
`/search?q=${encodeURI(q)}` // /search?q=cats%20&%20dogs ✗
// Better still, let the platform assemble it:
const url = new URL('https://example.com/search')
url.searchParams.set('q', 'cats & dogs')Pendekatan terakhir itu layak diadopsi sebagai kebiasaan. URL dan URLSearchParams adalah bawaan setiap peramban dan juga Node, dan mereka menerapkan pengodean yang tepat ke tiap bagian untuk Anda — yang menghapus keputusannya sepenuhnya ketimbang mengharuskan Anda melakukannya dengan benar secara manual setiap kali.
Mengapa spasi kadang + dan kadang %20
Dua spesifikasi berbeda ikut berperan, dan mereka tak sepakat tentang persis satu karakter. RFC 3986, yang mengatur URL secara umum, mengodekan spasi sebagai %20. Format application/x-www-form-urlencoded yang lebih lama, yang dikirim formulir HTML dan karenanya menjadi bentuk kebanyakan string kueri, mengodekan spasi sebagai +.
Jebakannya adalah decodeURIComponent hanya mengimplementasikan aturan pertama. Berikan hello+world kepadanya dan Anda mendapatkan hello+world kembali, plus dan semuanya — tanpa galat, tanpa peringatan, hanya nilai yang secara halus salah. Itulah sebabnya alat ini menawarkan opsi "perlakukan + sebagai spasi" dan menunjukkannya ketika masukan Anda mengandung sebuah plus sementara opsi itu mati.
Perhatikan bahwa URLSearchParams, yang menggerakkan tabel uraian di bawah alat, mengikuti aturan formulir dan memang mengubah + ke spasi. Jadi string kueri yang sama bisa didekode berbeda bergantung pada API mana yang Anda raih — secara sengaja, dan benar, di kedua kasus.
Satu konsekuensi yang layak diingat: jika sebuah plus benar-benar bagian dari data Anda — nomor telepon, ekspresi filter — ia harus dikodekan sebagai %2B. Sebuah + harfiah dalam string kueri paling banter hanya ambigu, dan akan dibaca sebagai spasi oleh kebanyakan pengurai.
Membaca URL
Tempel URL absolut dan alat ini membelahnya menjadi bagian-bagiannya. Layak diketahui apa nama masing-masing, karena pesan galat dan dokumentasi mengasumsikan kosakatanya:
- Skema — https, mailto, ftp. Segalanya sebelum titik dua, dan hal yang memutuskan bagaimana sisanya ditafsirkan.
- Info pengguna — user:password opsional sebelum host. Masih sah, dan masih ide buruk: ia dikirim dengan setiap permintaan dan berakhir di log, riwayat peramban, dan header perujuk.
- Host — nama domain atau alamat IP. Segalanya setelahnya ditangani server itu, bukan jaringan.
- Port — biasanya absen, karena 443 untuk https dan 80 untuk http tersirat.
- Origin — skema, host, dan port bersama. Ini adalah unit yang menjadi dasar keamanan peramban: kebijakan asal-sama, CORS, dan cakupan kuki semuanya membandingkan origin, bukan path.
- Path — bagian setelah host dan sebelum ? atau # mana pun.
- Kueri — pasangan kunci/nilai setelah ?, dipisah &.
- Fragmen — segalanya setelah #. Secara unik, ini tak pernah dikirim ke server; ia ditangani sepenuhnya oleh peramban.
Detail fragmen lebih penting daripada kedengarannya. Karena ia tak pernah meninggalkan peramban, apa pun yang Anda taruh setelah # tak terlihat oleh log server — itulah sebabnya beberapa aplikasi satu-halaman secara historis memakainya untuk perutean, dan mengapa ia bukan tempat untuk dilihat saat men-debug permintaan yang tak pernah tiba.
Peringatan terakhir tentang apa yang tak dilakukan pengodean. Persen-pengodean membuat teks aman untuk diangkut di dalam URL; ia bukan sanitasi dan bukan kendali keamanan. Mengodekan nilai tak membuatnya aman untuk diinterpolasi ke dalam HTML, SQL, atau perintah shell, dan mendekode masukan tak tepercaya bisa mengungkap karakter — pemisah path, bita null — yang disembunyikan bentuk terkodekan. Validasi apa nilai itu, terpisah dari mengodekan bagaimana ia dikirim.
Alamat yang Anda ketik tak selalu alamat yang dikirim
Sebelum URL pergi ke mana pun ia dinormalisasi, dan penulisan ulang itu senyap. Alat ini menampilkan hasilnya kapan pun ia berbeda dari masukan, karena string itu — bukan yang Anda ketik — adalah yang menjangkau server dan yang muncul dalam log:
HTTPS://Example.COM:443\a\b typed https://example.com/a/b sent
Empat aturan terpisah ikut memicu di sana. Skema dan host dijadikan huruf kecil, karena tak satu pun peka besar-kecil. Port dibuang karena 443 adalah default untuk https. Garis miring terbalik menjadi garis miring maju, aturan kompatibilitas yang mengejutkan orang yang menulis path bergaya-Windows. Dan path kosong akan menjadi garis miring tunggal. Tak satu pun dari ini merupakan galat, tetapi jika Anda membandingkan dua URL untuk melihat apakah keduanya sama, atau mencocokkan satu terhadap daftar-izin, Anda harus membandingkan bentuk ternormalisasi atau Anda akan mendapatkan jawaban yang salah.
Nama host dengan karakter non-ASCII ditulis ulang pula, menjadi bentuk ASCII yang diawali xn--, disebut punycode. Alat ini menampilkan kedua arah: nama terbaca dan yang benar-benar dikirim. Ini layak dilihat ketimbang dilewati, karena dua nama Unicode berbeda bisa tampak identik di layar — "a" Latin dan "а" Kiril adalah karakter terpisah — sambil menghasilkan punycode yang sepenuhnya berbeda. Membandingkan bentuk ASCII adalah satu-satunya cara andal membedakan pasangan seperti itu.
Satu hal tak pernah dinormalisasi: parameter kueri yang berulang. Menulis ?tag=a&tag=b sepenuhnya sah, dan standar tak mengatakan apa artinya, jadi setiap tumpukan memilih jawabannya sendiri. PHP menyimpan nilai terakhir, Express mengumpulkannya ke dalam larik, banyak kerangka kerja dan URLSearchParams.get mengambil yang pertama. Alat ini menandai kunci yang berulang ketimbang mendaftarnya dua kali tanpa komentar, karena bug yang dihasilkan — nilai yang bekerja di satu layanan dan lenyap di yang lain — benar-benar sulit dilihat dengan membaca.
Pertanyaan yang sering diajukan
- Apa perbedaan antara cakupan komponen dan URL penuh?
- Cakupan komponen meng-escape pembatas / ? : @ & = + pula, yang tepat untuk satu nilai yang ditaruh di dalam URL. Cakupan URL penuh membiarkannya utuh karena di sana mereka memisahkan bagian-bagian alamat. Memakai cakupan komponen pada seluruh URL mengubah setiap garis miring menjadi %2F dan menghasilkan satu string tak terpakai.
- Mengapa teks terdekode saya masih mengandung sebuah +?
- Karena decodeURIComponent mengikuti RFC 3986, tempat + hanya sebuah plus. Pengiriman formulir dan kebanyakan string kueri memakai pengodean formulir, tempat + berarti spasi. Nyalakan "perlakukan + sebagai spasi" ketika teksnya berasal dari salah satunya.
- Bagaimana saya mengodekan sebuah plus yang benar-benar sebuah plus?
- Tuliskan sebagai %2B. Sebuah + harfiah dalam string kueri akan dibaca sebagai spasi oleh kebanyakan pengurai, jadi plus mana pun yang benar-benar bagian dari data Anda — dalam nomor telepon, misalnya — harus di-escape.
- Apakah saya sebaiknya mengodekan seluruh URL atau hanya bagian-bagiannya?
- Hanya bagian-bagiannya, dan lebih baik bukan dengan tangan: bangun alamat dengan URL dan URLSearchParams, yang menerapkan pengodean yang benar ke tiap komponen. Mengodekan URL yang telah dirakit setelahnya adalah sumber kebanyakan bug pengodean-ganda.
- Mengapa uraian menampilkan URL yang berbeda dari yang saya tempel?
- Karena itulah yang dikirim. URL dinormalisasi sebelum dipakai: skema dan host dijadikan huruf kecil, port default dibuang, garis miring terbalik menjadi garis miring, path kosong menjadi garis miring, dan host non-ASCII menjadi punycode. Jika Anda membandingkan URL atau mencocokkan terhadap daftar-izin, bandingkan bentuk ternormalisasi ini ketimbang teks mentahnya.
- Mengapa tak ada uraian muncul untuk example.com/path?
- Karena ia bukan URL absolut — ia tak punya skema, jadi tak ada host untuk dikenali. Alat ini tak akan menebaknya untuk Anda: example.com:8080 sudah menjadi URL absolut yang valid yang skemanya example.com dan path-nya 8080, jadi diam-diam memberi prefiks https:// bisa menghasilkan uraian yang tampak masuk akal dan salah. Tambahkan sendiri skemanya dan bagian-bagiannya muncul.
- Apa itu pengodean ganda?
- Mengodekan nilai yang sudah dikodekan, jadi %20 menjadi %2520 — tanda persennya sendiri di-escape. Ia biasanya tampak sebagai urutan %20 harfiah yang muncul dalam halaman. Dekode sekali dan periksa apakah Anda masih melihat escape; jika ya, ia dikodekan dua kali.
- Apakah mengodekan nilai membuatnya aman?
- Tidak. Persen-pengodean adalah tentang transport, bukan keamanan. Nilai terkodekan tetaplah nilai yang sama seperti sebelumnya, dan ia butuh validasi yang sama dan escape yang sama sesuai konteksnya sebelum ia menjangkau HTML, SQL, atau shell.
- Mengapa fragmen tak dikirim ke server?
- Sesuai rancangan: segalanya setelah # ditangani peramban sendiri dan tak pernah muncul dalam permintaan. Itulah sebabnya ia tak bisa dilihat di log server, dan mengapa ia secara historis dipakai untuk perutean sisi-klien.
- Apakah yang saya tempel dikirim ke mana pun?
- Tidak. Pengodean, pendekodean, dan uraian URL semuanya memakai fungsi bawaan peramban sendiri dan berjalan sepenuhnya di perangkat Anda. Tidak ada yang Anda tempel meninggalkannya.
Alat terkait
- Escape / unescape string JSON
Escape teks untuk string JSON, atau baca yang ter-escape kembali.
- Pengode / pendekode entitas HTML
Escape teks untuk HTML, atau ubah entitas kembali menjadi karakter.
- Generator Data URI
Ubah berkas atau teks menjadi data: URI, dan baca kembali satu.
- Base64
Kodekan dan dekode Base64 — dukungan UTF-8 penuh.