JavaScript: 10 Menit Dengan XMLHttpRequest & AJAX

Jangan membuat pengunjung web menunggu terlalu lama

Nauval
Nauval
Oct 25, 2019 · 9 min read

JavaScript merupakan bahasa yang paling banyak digunakan selama 6 tahun berturut-turut hingga 2018 menurut StackOverflow Development Survey. Pada tulisan ini saya asumsikan kamu sudah paham dengan asynchronous, HTTP, client/server dan tentunya JavaScript object.

Mukadimah

Hypertext Transfer Protocol (HTTP) adalah protokol yang di gunakan World Wide Web (WWW) untuk mengirim data antar 2 sistem, yang selanjutnya disebut Client & Server, HTTP Client itu bentuknya beragam, bisa Browser, Headless Browser, cURL dan lainya, untuk HTTP Server juga beragam, dan ditulis di berbagai bahasa pemrograman atau web server, misalnya PHP, GoLang, NGINX, APACHE, NodeJS HTTP Server, dan banyak lagi.

XHR atau XMLHttpRequest merupakan browser built-in XMLHttpRequest object, salah satu object yang terdapat pada JavaScript untuk melakukan permintaan (request) data dari klien ke server. Bila merujuk ke HTTP maka XHR memiliki posisi sebagai client. Sederhananya, XHR adalah HTTP client yang dimiliki oleh JavaScript untuk melakukan permintaan data ke server.

Kita tidak akan membuat HTTP server atau REST API sendiri untuk uji cobanya. Kita akan menggunakan layanan dari Reqres.in. Reqres.in dapat kita gunakan gratis untuk menguji kode XHR yang kita buat berjalan dengan baik atau tidak sebelum kita menggunakan REST API yang sungguhan.

Seluruh browser modern telah mendukung object JavaScript ini. Cara menggunakan object ini sangat mudah, contoh penggunaannya seperti berikut,

var http = new XMLHttpRequest(); // inisialisasi
http.addEventListener("load", () => {
// callback, ketika server memberi response
console.log(http.responseText);
});
http.open("GET", "https://reqres.in/api/users"); // tentukan server tujuan
http.send(); // eksekusi

Maka kode di atas akan menghasilkan output berikut,

{"page":1,"per_page":3,"total":12,"total_pages":4,"data":[{"id":1,"first_name":"George","last_name":"Bluth","avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/calebogden/128.jpg"},{"id":2,"first_name":"Janet","last_name":"Weaver","avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"},{"id":3,"first_name":"Emma","last_name":"Wong","avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/olegpogodaev/128.jpg"}]}

Untuk melihat rincian seputar request yang dibuat kita dapat melihatnya melalui Developer Tools (F12) > Network.

DevTools (Chrome)

Kenapa bisa menghasilkan output seperti di atas? Karena, kode XHR yang kita tulis di atas melakukan permintaan (request) ke server reqres.in, lebih tepatnya ke endpoint /api/users dan di dalam endpoint tersebut sudah ditentukan untuk memberikan hasil (response) di atas dengan format JSON.

XHR bersifat asynchronous, itu berarti JavaScript akan mengeksekusi kode XHR dan membiarkannya berjalan di latar belakang. Perhatikan kode berikut:

alert(1);

Ketika kode JavaScript di atas dijalankan, maka yang akan terjadi:

  • Pertama, hasil dari kode alert(1); akan muncul
  • Kedua, kode XHR akan dieksekusi dan berjalan di latar belakang
  • Ketiga, hasil dari kode alert(2); akan muncul
  • Keempat, response dari server akan muncul di console browser

Kenapa response dari server muncul terakhir? Karena, setelah mengeksekusi kode XHR, berikutnya JavaScript langsung mengeksekusi kode berikutnya (kode alert(1); — tidak menunggu sampai kode XHR memberikan response. Itu kenapa kode console.log diletakkan di dalam callback. Karena kode console.log dieksekusi hanya pada saat server telah memberikan response-nya (terlepas response success atau error). Itu yang dimaksud dengan asynchronous.

Kira-kira dapat digambarkan seperti berikut untuk cara berkomunikasi XHR JavaScript dengan HTTP Server.

Ilustrasi komunikasi XHR JavaScript dengan HTTP Server

Response yang diberikan oleh server dapat berformat webpage HTML, XML, JSON atau jenis dokumen lainnya bergantung pada pembuat HTTP Server tersebut.

Apa manfaat XHR?

Berdasarkan segala sesuatu yang telah saya jelaskan sebelumnya, dengan XHR kita dapat melakukan transaksi data antara client dan server dibelakang layar, melakukan perpindahan webpage tanpa harus me-reload seluruh isi webpage, mengkonsumsi RESTful API dan yang lainnya.

Lebih dalam dengan XHR

Untuk memulai menggunakan XHR dalam melakukan permintaan data, dapat dimulai dengan menginisialisasi class XHR tersebut.

var http = new XMLHttpRequest();

Return dari class tersebut adalah sebuah object yang terdiri dari property dan method dengan fungsinya masing-masing:

XMLHttpRequest {onreadystatechange: null, readyState: 0, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}

Namun, bila kamu menggunakan browser lawas seperti IE 5 dan IE 6 maka kamu harus melakukan cara yang berbeda untuk menginisialisasi XHR.

var http = new ActiveXObject("Microsoft.XMLHTTP");

Untuk mengatasi hal ini, kamu bisa melakukan pengecekan apakah browser mendukung XHR atau tidak dengan cara seperti berikut,

var http;
if (window.XMLHttpRequest) {
// code for modern browsers
http = new XMLHttpRequest();
} else {
// code for old IE browsers
http = new ActiveXObject("Microsoft.XMLHTTP");
}

Dari kode di atas kita dapat lihat bahwa jika browser mendukung XHR maka akan menggunakan class XMLHttpRequest() dan bila menggunakan browser lawas maka akan menggunakan class ActiveXObject() untuk menginisialisasinya.

Setelah itu, untuk memulai melakukan request, kamu harus menentukan dahulu endpoint dan method yang akan digunakan untuk melakukan request. Kedua hal tersebut bergantung pada HTTP Server yang kamu gunakan. Dalam kasus ini kita akan menggunakan Reqres.in sebagai HTTP Server kita untuk meng-handle request dan memberikan response.

Gunakan method .open(method, url, async, user, password).

Secara default, method .open() pada XHR memerlukan 5 parameter yang perlu diisi, namun yang dibutuhkan hanya 2 parameter saja, yaitu URL dan method. Parameter URL diisi dengan nilai URL endpoint server tujuan kita. Sedangkan mehtod diisi dengan jenis method HTTP yang akan digunakan, method ini bergantung pada URL endpoint, seperti GET, POST, DELETE, PATCH , OPTIONS , PUT atau yang lainnya.

Sebagai contoh, kita akan mengambil data users dari endpoint /api/users di server Reqres.in. Endpoint tersebut dapat diakses dengan method GET. Maka kita hanya perlu menambahkan URL dan method tadi ke dalam method .open() XHR.

xhr.open("GET", "https://reqres.in/api/users");

Seperti yang kita bahas sebelumnya, method .open() memiliki 5 parameter, yaitu method, URL, async, user dan password. Parameter URL dan method sudah kita bahas, sekarang kita akan bahas sisanya:

  • Async merupakan optional parameter yang menentukan apakah proses XHR ini asynchronously atau tidak. Parameter ini diisi dengan boolean yaitu, true atau false. Default-nya adalah true. Bila parameter ini diisi dengan false, maka kode di bawah XHR tidak akan dieksekusi hingga proses transaksi XHR selesai.
  • User dan password merupakan optional parameter yang digunakan bila endpoint membutuhkan authentication.

Bila URL dan method sudah ditentukan, saatnya “meluncurkan” permintaan ke server dengan menggunakan method .send() dari XHR.

xhr.send();

Permintaan tidak akan diekskusi atau “diluncurkan” sampai method .send() pada XHR dipanggil.

Sampai sini kita sudah menulis kode berikut,

var xhr = new XMLHttpRequest();
xhr.open("GET", "https://reqres.in/api/users");
xhr.send();

Dengan kode di atas kita sudah dapat melakukan permintaan data terhadap server, namun kita belum bisa menerima data dari URL tersebut.

Karena kita menggunakan asynchronous maka intuk meng-handle response data dari server maka kita perlu menggunakan event listener yang tersedia pada XHR, yaitu load. Kira-kira seperti berikut,

xhr.addEventListener("load", () => {
console.log("transfer selesai");
});

Event tersebut akan di-fire atau dieksekusi saat permintaan telah di-response oleh server. Selain event listener load ada juga yang lainnya, seperti progress, error, abort dan lainnya.

Untuk mengambil data response yang diberikan server kita dapat menggunakan property responseText pada XHR object.

xhr.addEventListener("load", () => {
console.log(xhr.responseText);
});

Sampai sini kita sudah dapat melakukan request dan response HTTP dengan XML Http Request (XHR). Kesuluruhan kodenya maka seperti berikut,

var xhr = new XMLHttpRequest();
xhr.open("GET", "https://reqres.in/api/users");
xhr.send();
xhr.addEventListener("load", () => {
console.log(xhr.responseText);
});

Request di atas akan menghasilkan response seperti berikut,

{"page":1,"per_page":3,"total":12,"total_pages":4,"data":[{"id":1,"first_name":"George","last_name":"Bluth","avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/calebogden/128.jpg"},{"id":2,"first_name":"Janet","last_name":"Weaver","avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"},{"id":3,"first_name":"Emma","last_name":"Wong","avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/olegpogodaev/128.jpg"}]}

Response di atas adalah berformat JSON.

Untuk mengetahui response yang diterima galat atau sukses, kita dapat menggunakan response status code yang diterima XHR dari server. Response status tersebut dapat diambil menggunakan property .status dari XHR object. Pada HTTP, response code yang menunjukan request sukses adalah 200 hingga 226. Maka kita akan membuatnya seperti berikut,

xhr.addEventListener("load", () => {
if(xhr.status >= 200 && xhr.status <= 226) {
console.log(xhr.responseText);
}else{
console.log("Galat");
}
});

Kode di atas akan menampilkan response dari server bila response status lebih dari sama dengan 200 dan kurang dari sama dengan 226. Bila response status di luar itu maka akan menampilkan teks “Galat” pada console browser.

Sampai sini kita sudah memahami request method GET dan response pada HTTP dengan XHR object.

Membuat request POST

Setelah sebelumnya mencoba membuat request dengan method GET. Maka kali ini kita akan membuat request dengan method POST. Apa bedanya? Method GET cenderung untuk mengambil data spesifik dan digunakan untuk mengambil data saja, sedangkan POST umumnya digunakan untuk membuat sesuatu yang baru pada server, seperti meng-create record baru atau yang lainnya.

Dalam kasus ini kita akan mencoba membuat data pengguna baru dengan endpoint yang terdapat pada server Reqres.in, yaitu POST /api/users. Pada endpoint tersebut, kita perlu mengirim parameter data yang berisi name dan job. Misal,

name=Muhamad Nauval Azhar&job=Junior Web Developer

Untuk melakukan request POST sama saja halnya seperti kita melakukan request GET. Kode yang digunakan pun hampir sama, hanya saja ada sedikit tambahan dan perubahan.

Perubahan yang perlu dilakukan adalah merubah method GET menjadi POST pada method .open() di XHR object.

Lalu, menambahkan nilai parameter name=Muhamad Nauval Azhar&job=Back-end Developer ke dalam method .send(data) pada XHR object.

Terakhir, menambahkan header Content-Type pada XHR object. Header merupakan sebuah informasi seputar rincian permintaan yang diberikan kepada server.

xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

URL tidak akan kita ubah, karena kita menggunakan URL yang sama hanya saja method-nya yang berbeda. Keseluruhan kode akan seperti berikut,

var xhr = new XMLHttpRequest();
xhr.open("POST", "https://reqres.in/api/users");
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("name=Muhamad Nauval Azhar&job=Back-end Developer");
xhr.addEventListener("load", () => {
console.log(xhr.responseText);
});

Request di atas akan menghasilkan output seperti berikut,

{"name":"Muhamad Nauval Azhar","job":"Back-end Developer","id":"4","createdAt":"2018-06-16T04:41:23.683Z"}

Sampai sini kita sudah mencoba membuat request dengan method GET dan POST.

Implementasi XHR dengan HTML

Sekarang kita akan mengimplementasikan XHR dengan HTML. Dalam kasus ini kita akan membuat sebuah form dengan kolom input Name dan Job. Lalu ditambakan dengan sebuah tombol action yang ketika diklik akan mengirim request ke server Reqres.in pada endpoint POST /api/users.

Untuk struktur HTML-nya kira-kira seperti berikut,

<form id="create-user">
<label for="name">Name</label>
<input name="name" id="name">
<br><br>
<label for="job">Job</label>
<input name="job" id="job">
<br><br>
<button type="submit" id="submit-form">
Create User
</button>
</form>

Kode HTML di atas akan menampilkan 2 kolom input Name dan Job. Ada juga tombol dengan teks Create User.

Pertama, kita perlu membuat halaman tidak reload ketika form di-submit. Sebelum itu, silakan kode JavaScript yang kamu tulis itu akan diletakkan sebagai inline script dengan menggunakan tag <script>.

Berikutnya, agar memberikan user-experience yang lebih baik maka kita akan memberikan sebuah wadah informasi mengenai XHR yang kita buat. Informasi tersebut seperti, data pengguna telah dibuat, informasi galat atau yang lainnya. Informasi tersebut nantinya akan ditampilkan pada sebuah tag div HTML.

Mari kita buat tag div HTML dengan identifier atau ID info-box.

<div id="info-box"></div>

Letakkan kode tersebut di bawah form.

Lalu kita akan mengakses element tersebut pada JavaScript menggunakan method .getElementById().

var info_box = document.getElementById("info-box");

Letakkan kode di atas setelah variable create_user_form.

Pertama, kita akan memberikan informasi bahwa request sedang dilakukan. Maka kodenya seperti berikut,

info_box.innerHTML = "Permintaan sedang dikirim ...";

Letakkan kode di atas pada baris pertama di dalam listener submit pada form.

..
...
create_user_form.addEventListener("submit", (event) => {
info_box.innerHTML = "Permintaan sedang dilakukan ...";
...
..
.

Kemudian, kita akan memberi informasi ketika request telah selesai (entah itu galat atau sukses).

info_box.innerHTML = "Permintaan telah selesai. <br> Status: " + xhr.status + "<br> Response Text: " + xhr.responseText;

Letakkan kode tersebut di dalam listener load pada XHR object.

...
xhr.addEventListener("load", () => {
info_box.innerHTML = "Permintaan telah selesai. <br> Status: " + xhr.status + "<br> Response Text: " + xhr.responseText;
..
});
...
..

Bila digabungkan, keseluruhan kode akan seperti berikut,

Untuk HTML

<form id="create-user">
<label for="name">Name</label>
<input name="name" id="name">
<br><br>
<label for="job">Job</label>
<input name="job" id="job">
<br><br>
<button type="submit" id="submit-form">
Create User
</button>
</form>
<div id="info-box"></div>

Untuk JavaScript

var create_user_form = document.getElementById("create-user"),
info_box = document.getElementById("info-box");

create_user_form.addEventListener("submit", (event) => {
info_box.innerHTML = "Permintaan sedang dilakukan ...";

var input_name = document.querySelector("input[name=name]").value,
input_job = document.querySelector("input[name=job]").value;

var xhr = new XMLHttpRequest();
xhr.open("POST", "https://reqres.in/api/users");
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("name="+ input_name +"&job=" + input_job);
xhr.addEventListener("load", () => {
info_box.innerHTML = "Permintaan telah selesai. <br> Status: " + xhr.status + "<br> Response Text: " + xhr.responseText;
console.log(xhr.responseText);
});

event.preventDefault();
});

Untuk mengujinya silakan gunakan JSFiddle berikut ini,

XHR Demo

Bila berhasil akan menampilkan format teks berikut ini pada info box.

Permintaan telah selesai. 
Status: 201
Response Text: {"name":"Muhamad Nauval Azhar","job":"Web Developer","id":"618","createdAt":"2018-06-16T05:47:14.077Z"}

Sampai sini kita sudah mengimplementasikan XHR dengan HTML.

Untuk lebih detail lagi seputar XHR maka kamu dapat membaca dokumentasinya di sini.


AJAX

Lalu bagaimana dengan AJAX? Apa itu AJAX? Bedanya apa dengan XHR?

AJAX kependekan dari Asynchronous JavaScript And XML. Nama AJAX, bila digunakan saat ini, –bagi saya– sungguh menyesatkan. Dengan menggunakan “XML”, seolah-olah AJAX hanya mendukung HTTP server yang memberikan response data berformat XML. Padahal, kebanyakan orang sudah menggunakan JSON atau bahkan plain text belakangan ini. Jadi, mungkin nama AJAX perlu diganti menjadi AJAJ (Asynchronous JavaScript And JSON) atau AJAP (Asynchronous JavaScript And Plain text) atau AJAW (Asynchronous JavaScript And Whatever).

Becanda.

Tentu saja AJAX ada hubungannya dengan XHR. Karena, AJAX menggunakan XHR di dalamnya. Bila kamu pernah menggunakan jQuery, jQuery memiliki API $.ajax untuk melakukan HTTP request ke server. Dengan menggunakan $.ajax itu sama saja kamu menggunakan XHR, hanya saja jQuery memberikan fitur tambahan pada “XHR”-nya, seperti kompatibilitas lintas browser.

Jadi, kalau kamu menggunakan jQuery, lebih baik gunakan kode $.ajax ketimbang XMLHttpRequest . Karena lebih mudah digunakan. Tapi, kalau kamu menggunakan vanilla JavaScript, jangan sampai me-load jQuery hanya karena ingin menggunakan $.ajax -nya saja — gunakan XMLHttpRequest .

Sudah itu saja soal AJAX dan XHR. Semoga bermanfaat.


Ikuti Instagram @itskodinger untuk mendapatkan update seputar pemrograman atau teknologi lainnya. Jangan lupa gabung grup Kodinger di Telegram.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade