Fitur pencarian katalog toko Budi menghasilkan tautan seperti https://toko.example/katalog?kata=kamus&urut=harga. Karena menyusun tautan itu dengan gabungan string, Budi pernah menulis "?kata=" + kataKunci — dan tautannya rusak begitu pengunjung mencari frasa berisi spasi atau tanda &, misalnya “buku & novel”. Karakter yang punya makna khusus di dalam URL tidak boleh ditempel mentah-mentah ke string. Browser menyediakan dua object bawaan untuk menyelesaikan masalah ini: URL untuk membedah dan membangun URL, serta URLSearchParams untuk mengelola query string-nya dengan aman.
Keduanya bukan API khusus browser saja — spesifikasinya (WHATWG URL Standard) diikuti Node juga, sehingga berkas contoh di chapter ini bisa dijalankan langsung dengan node nama-berkas.js. Di halaman web, object yang sama tersedia sebagai global.
Membedah URL dengan new URL #
Aturannya: new URL(urlLengkap) mengurai string menjadi object dengan properti terpisah untuk setiap bagian. Dari satu string panjang, kita bisa membaca protokol, host, jalur, query string, dan fragment tanpa memotong string secara manual:
// urai-url.js — membedah URL menjadi bagian-bagiannya dengan new URL()
const tautan = new URL(
"https://toko.example/katalog?kategori=buku&halaman=2#hasil"
);
console.log("protokol :", tautan.protocol);
console.log("host :", tautan.host);
console.log("pathname :", tautan.pathname);
console.log("search :", tautan.search);
console.log("hash :", tautan.hash);
console.log("origin :", tautan.origin);
// URL relatif membutuhkan URL dasar sebagai argumen kedua
const relatif = new URL("/promo/agustus", "https://toko.example");
console.log("relatif :", relatif.href);Output yang Dihasilkan:
protokol : https:
host : toko.example
pathname : /katalog
search : ?kategori=buku&halaman=2
hash : #hasil
origin : https://toko.example
relatif : https://toko.example/promo/agustusMari kita telaah baris-baris pentingnya:
- Baris 3–5 (
new URL(...)): constructor menerima URL absolut — lengkap dengan protokolnya. Bila string bukan URL valid, constructor melemparTypeErrordengan pesan sepertiInvalid URL, sehingga input dari pengguna bisa divalidasi lewattry-catch. - Baris 7–12 (pembacaan properti): setiap bagian URL tersedia sebagai properti.
searchmemuat tanda tanya beserta seluruh query string;hashmemuat tanda pagar dan teks setelahnya;originmenggabungkan protokol dan host — berguna untuk membandingkan asal dua tautan. - Baris 15 (
new URL("/promo/agustus", dasar)): URL relatif tidak cukup sendirian karena hasilnya bergantung pada titik awal. Argumen kedua memberi URL dasar, dan constructor menggabungkan keduanya menjadihttps://toko.example/promo/agustus.
Tabel berikut merangkum properti yang paling sering dibaca:
| Properti | Isi pada contoh di atas |
|---|---|
href | URL utuh: https://toko.example/katalog?kategori=buku&halaman=2#hasil |
protocol | https: — catat tanda titik dua ikut menyertai |
host | toko.example — hostname plus port (bila ada) |
pathname | /katalog — jalur tanpa query dan hash |
search | ?kategori=buku&halaman=2 — seluruh query string |
hash | #hasil — fragment di akhir URL |
origin | https://toko.example — protokol plus host, tanpa jalur |
Object URL juga bersifat dapat diubah (mutable): menulis ke satu properti memperbarui href sekaligus. tautan.pathname = "/katalog/anak" langsung mengubah URL utuhnya — tanpa membangun ulang string dari awal. Cara sebaliknya juga bisa: String(tautan) mengembalikan href sebagai string biasa, siap ditempel ke atribut href tautan atau dikirim ke fetch().
Membangun Query String dengan URLSearchParams #
Membangun tautan kebalikannya: kita punya data (kata kunci, urutan, tag) dan perlu menggabungkannya menjadi query string. Properti tautan.searchParams memberi object URLSearchParams yang terhubung langsung dengan URL pemiliknya — setiap perubahan pada params langsung terlihat di tautan.href:
// bangun-tautan.js — membangun dan mengubah query string secara aman
const tautan = new URL("https://toko.example/katalog");
const params = tautan.searchParams;
// --- 1. menambah parameter: set dan append ---
params.set("kata", "kamus mini"); // nilai berisi spasi: di-encode otomatis
params.set("urut", "harga");
params.append("tag", "baru");
params.append("tag", "promo"); // append menambah, bukan mengganti
console.log("tautan :", tautan.href);
console.log("kata :", params.get("kata"));
console.log("tag :", params.getAll("tag").join(", "));
console.log("halaman ada?", params.has("halaman"));
// --- 2. mengubah dan menghapus parameter ---
params.set("halaman", "2");
params.delete("urut");
console.log("akhir :", tautan.href);
// --- 3. karakter khusus tetap aman tanpa pengodean manual ---
params.set("kata", "buku & novel");
console.log("search :", tautan.search);
console.log("terbaca:", params.get("kata"));Output yang Dihasilkan:
tautan : https://toko.example/katalog?kata=kamus+mini&urut=harga&tag=baru&tag=promo
kata : kamus mini
tag : baru, promo
halaman ada? false
akhir : https://toko.example/katalog?kata=kamus+mini&tag=baru&tag=promo&halaman=2
search : ?kata=buku+%26+novel&tag=baru&tag=promo&halaman=2
terbaca: buku & novelMari kita bedah method-methodnya:
- Baris 4 (
tautan.searchParams):URLSearchParamsdiambil dari URL-nya. Keduanya saling terhubung — perubahan di satu sisi langsung tercermin di sisi lainnya. - Baris 7 (
params.set("kata", ...)):set(kunci, nilai)menambah parameter baru atau menimpa nilai yang sudah ada. Spasi pada “kamus mini” dikodekan menjadi+di dalamhreftanpa kita campur tangan. - Baris 9–10 (
params.append(...)):appendmenambah nilai tanpa menghapus nilai sebelumnya, sehingga kuncitagmuncul dua kali.get("tag")hanya mengembalikan yang pertama;getAll("tag")mengembalikan seluruhnya sebagai array. - Baris 15 (
params.has("halaman")):hasmemeriksa keberadaan kunci sebelum kita membacanya — hasilnyafalsekarena parameter itu belum ditambahkan. - Baris 18–19 (
setdandelete):set("halaman", "2")menambah parameter di posisi akhir;delete("urut")menghapus kunci beserta seluruh nilainya dari URL. - Baris 23–25 (karakter khusus): nilai “buku & novel” memuat
&— karakter pemisah parameter. Di dalamsearchia tampil sebagai%26, danget("kata")mengembalikannya utuh kembali. Pengodean dan dekode berjalan dua arah secara otomatis.
Membaca Parameter dari Halaman Saat Ini #
Arah sebaliknya juga sering dibutuhkan: halaman katalog dibuka dengan URL yang sudah memuat parameter, lalu JavaScript membacanya untuk menyiapkan tampilan. Properti location.search berisi query string halaman aktif, dan URLSearchParams bisa menerima string itu langsung:
const params = new URLSearchParams(location.search);
const kata = params.get("kata") ?? "";
const halaman = Number(params.get("halaman") ?? "1");
console.log("kata kunci:", kata);
console.log("halaman :", halaman);Keluaran console browser:
kata kunci: kamus mini
halaman : 2Keluaran di atas mengasumsikan halaman dibuka pada URL https://toko.example/katalog?kata=kamus+mini&halaman=2; nilai tampil sudah terdekode kembali, tanpa tanda + maupun %26.
Properti hash layak mendapat satu catatan tersendiri. Bagian URL setelah # tidak pernah dikirim ke server — ia hanya dipakai browser untuk melompat ke jangkar (anchor) pada halaman, dan aplikasi satu halaman memakainya untuk rute seperti #/katalog/promo. Membaca dan mengubahnya memakai properti tautan.hash, dan perubahan dari tautan yang diklik pengunjung dilaporkan lewat event hashchange pada window — jalan pintas routing yang lebih tua daripada History API pada chapter berikutnya.
Sementara itu, origin adalah properti yang paling sering dipakai untuk keputusan keamanan: membandingkan tautanBaru.origin === location.origin memastikan tautan berada pada situs yang sama sebelum kode kita memperlakukannya secara khusus. Prinsip pemeriksaan ini kita kenali lagi di section Security sebagai bagian dari validasi URL.
Aturan pengodean URL sendiri (karakter mana yang harus dikodekan, perbedaan %20 dengan +) kita bedah lebih rinci di chapter URL Encoding pada section Data dan Serialization. Untuk pekerjaan sehari-hari — membedah tautan, membangun query string, membaca parameter halaman — pasangan URL dan URLSearchParams di chapter ini sudah menutup semua kebutuhannya.
Rangkuman pembagiannya begini: URL untuk URL utuh — validasi, pembacaan bagian, perubahan jalur; URLSearchParams untuk isi query string — tambah, baca, hapus parameter. Keduanya terhubung lewat properti searchParams, dan keduanya mengikuti spesifikasi yang sama di browser maupun Node, sehingga kode pemroses tautan kita bisa dipakai di kedua lingkungan tanpa penyesuaian.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
bangun-tautan.js
Unduh berkas// bangun-tautan.js — membangun dan mengubah query string secara aman
const tautan = new URL("https://toko.example/katalog");
const params = tautan.searchParams;
// --- 1. menambah parameter: set dan append ---
params.set("kata", "kamus mini"); // nilai berisi spasi: di-encode otomatis
params.set("urut", "harga");
params.append("tag", "baru");
params.append("tag", "promo"); // append menambah, bukan mengganti
console.log("tautan :", tautan.href);
console.log("kata :", params.get("kata"));
console.log("tag :", params.getAll("tag").join(", "));
console.log("halaman ada?", params.has("halaman"));
// --- 2. mengubah dan menghapus parameter ---
params.set("halaman", "2");
params.delete("urut");
console.log("akhir :", tautan.href);
// --- 3. karakter khusus tetap aman tanpa pengodean manual ---
params.set("kata", "buku & novel");
console.log("search :", tautan.search);
console.log("terbaca:", params.get("kata"));
urai-url.js
Unduh berkas// urai-url.js — membedah URL menjadi bagian-bagiannya dengan new URL()
const tautan = new URL(
"https://toko.example/katalog?kategori=buku&halaman=2#hasil"
);
console.log("protokol :", tautan.protocol);
console.log("host :", tautan.host);
console.log("pathname :", tautan.pathname);
console.log("search :", tautan.search);
console.log("hash :", tautan.hash);
console.log("origin :", tautan.origin);
// URL relatif membutuhkan URL dasar sebagai argumen kedua
const relatif = new URL("/promo/agustus", "https://toko.example");
console.log("relatif :", relatif.href);