Teknologi Informasi dan Pemerintahan: Tentang Fenomena Baru ‘Open Data’ di Indonesia

Indonesia akhir-akhir ini sedang ramai memperbincangkan hasil Pemilu Presiden RI 2014. Ketika hasil quick count lembaga survei tidak seragam, banyak pihak yang kemudian melakukan klaim-klaim pemenangan yang aneh. Lucunya, saya pribadi justru merasa tersulut untuk ikut merespon sekarang, setelah pemilu selesai, bukan saat masa kampanye pemilihan presiden. :D

Ngg, maaf, maaf, bukan ini inti pembicaraan yang ingin saya sampaikan. :P

Saya salut sekali dengan Komisi Pemilihan Umum Republik Indonesia. Tahun ini, data Daftar Pemilih yang boleh mencoblos serta rekap hasil Pemilu Presiden semuanya bisa dilihat di alamat http://data.kpu.go.id dan http://pilpres2014.kpu.go.id. Dengan menggunakan halaman ini, seluruh data yang ada dapat dipantau oleh publik, sehingga siapapun yang berminat untuk melihat datanya dengan lebih teliti bisa langsung bertindak dengan cepat. Di Twitter sampai ada hastag #KawalKPU segala untuk merepresentasikan tindakan netizen yang ingin melihat hasil pemilu yang bersih dari kecurangan.

Akibatnya, KPU harus bersabar dalam menerima berbagai macam jenis kritik, koreksi, dan juga sentimen dari Rakyat Indonesia yang ingin mengawal proses pemilu. Ini sebuah fenomena yang menurut saya sangat positif. Semakin banyak rakyat yang merasa terlibat dalam menyelesaikan masalah yang ada, kemudian “turun tangan” (pinjam istilah Pak Anies Baswedan) untuk bertindak, maka tentu saja Indonesia yang maju bisa segera berubah dari retorika dalam wacana menjadi kenyataan. ;)

Fenomena ini adalah sebuah kemajuan yang sangat luar biasa. Jika hal seperti ini dilanjutkan, tidak hanya di KPU saja, tapi juga di lembaga-lembaga pemerintah lainnya, saya rasa frase Transparansi Publik akan jadi sebuah kenyataan yang benar-benar terimplementasi. :) Bayangkan kalau seluruh data yang memang seharusnya diketahui oleh Rakyat Indonesia seperti progress pengembangan infrastruktur pembangunan, pajak, dan data-data terkait dengan pendidikan bisa diakses dan dipantau publik. Rakyat Indonesia akan bisa terlibat langsung dalam mengawasi dan akhirnya akan lebih optimis terhadap hasil kerja politisi-politisi yang menjadi wakil rakyat di pemerintahan.

Tampilan halaman pilpres2014.kpu.go.id.
Tampilan halaman pilpres2014.kpu.go.id.

Indonesia di masa Pak SBY sudah memiliki Unit Kerja Presiden Bidang Pengawasan dan Pengendalian Pembangunan (UKP4). Coba kunjungi http://ukp.go.id. Salah satu programnya adalah Open Government Indonesia (OGI). Coba baca lebih detailnya di http://www.opengovindonesia.org. Salah satu produknya yang saya tahu adalah LAPOR, singkatan dari Laporan Aspirasi dan Pengaduan Online Rakyat, sebuah aplikasi berbasis web dan mobile yang bisa digunakan oleh Rakyat Indonesia untuk memberikan aspirasi, ataupun melaporkan semua hal yang terkait dengan pemerintahan. Ada infrastruktur lalu lintas yang rusak? LAPOR saja. Ada kantor pemerintah yang menerapkan pungutan liar? LAPOR lagi. Hasil dari setiap pelaporannya akan diproses lebih lanjut hingga ditindak. Coba saja kunjungi website-nya di alamat http://lapor.kpu.go.id.

Tampilan website lapor.ukp.go.id.
Tampilan website lapor.ukp.go.id.

Hal-hal positif seperti ini malah jarang disorot media ya? Hihi.

Terkait dengan optimisasi penggunaan Teknologi Informasi di pemerintahan, menurut saya, ada 2 hal, yang jika diimplementasikan, akan meningkatkan kualitas dari fenomena open data ini. Hal tersebut adalah tentang pengembangan peranti lunak pemerintah yang open source dan adanya sentralisasi data publik.

 

Tentang Peranti Lunak Pemerintah yang Open Source

Beberapa bulan yang lalu, saya sempat dimintai saran oleh teman saya tentang pengembangan e-procurement di kantor pemerintah. Saat itu saya masih belum tahu apa-apa tentang peranti lunak yang ada kaitannya dengan pemerintahan. Di pikiran saya, setiap kantor pasti harus mengembangkan peranti lunak sendiri-sendiri dan kemudian harus mempersiapkan infrastrukturnya sendiri pula.

Setelah melakukan browsing, barulah saya tahu, kalau ternyata peranti lunak e-procurement sudah tersentralisasi dan dikembangkan langsung oleh pemerintah. Waktu itu saya membaca informasinya di alamat http://eproc.lkpp.go.id. Jadi, ada namanya Layanan Pengadaan Secara Elektronik atau disingkat LPSE. LPSE ini adalah peranti lunak berbasis web yang dikembangkan untuk menangani lelang pengadaan barang/jasa secara digital. Coba saja googling dengan kata kunci “LPSE”, nanti akan muncul banyak contoh LPSE yang telah terdistribusi. Setelah saya perhatikan, ternyata LPSE ini sudah terimplementasi di banyak provinsi.

Saya sangat tertarik dengan hal ini, sehingga saya mencari-cari informasi lainnya. Ternyata peranti lunaknya didistribusikan secara gratis (free license). Aplikasinya sepertinya dikembangkan dengan menggunakan Java. Bahkan, sistem proteksi dokumennya juga sudah tersedia. Waktu itu di halaman yang saya cantumkan di atas, saya membaca tentang beberapa prosedur implementasi yang dapat dilakukan. Sayangnya, dokumentasinya menurut saya masih berantakan, dan bahkan pedoman instalasinya juga kurang jelas. Link untuk men-download salinan aplikasinya juga tidak ada di halaman itu. Saya rasa untuk mendapatkan informasi lengkap, mau tidak mau harus bertanya langsung ke humas Lembaga Kebijakan Pengadaan Barang Jasa Pemerintah (LKPP) selaku yang membawahi, dan itu berarti agak susah.

Mungkin ada beberapa faktor pertimbangan yang membuat pengembang LPSE tidak menjadikan peranti lunak ini open source. Namun, seandainya saja aplikasi ini open source, pemerintah bisa mendapatkan masukan yang lebih banyak terkait dengan implementasi teknis dan mungkin non-teknisnya. Di luar sana ada banyak pengembang peranti lunak yang antusias untuk memberi masukan dan tentunya bisa dijadikan bahan pertimbangan baru bagi pengembang peranti lunak tersebut di pemerintahan agar dapat mengimplementasikan best practice untuk peranti lunak yang ada.

Peranti lunak seperti LPSE milik LKPP ini hanya salah satu contoh yang saya tahu saja. Mungkin ada banyak peranti lunak lain yang juga dikembangkan sendiri oleh pemerintah. Andaikan semuanya open source, hehe.

Sebagai contoh, di Inggris, pencarian informasi terkait dengan layanan pemerintahan sangat mudah, tinggal kunjungi https://www.gov.uk. Di sana, informasi seperti passport, aturan tax, bahkan aturan untuk berkendara bagi pejalan kaki, pengguna sepeda, dan kendaraan juga tersedia. Menariknya lagi, source code-nya dibuka untuk umum. Coba kunjungi https://github.com/alphagov.

 

Tentang Sentralisasi Data Publik

Beberapa waktu yang lalu, saya dan teman saya kebetulan mendapatkan sebuah pekerjaan yang membutuhkan data provinsi dan kabupaten yang ada di seluruh Indonesia. Saat itu saya hanya bisa memasang ekspresi bingung. Ke mana saya harus mencari datanya? :|

Hal yang relatif sepele seperti ini, aslinya sangat penting. Ada banyak aplikasi yang dalam praktiknya pasti membutuhkan data-data seperti ini. Pendaftaran mahasiswa misalnya. Pihak universitas jika menyediakan aplikasi pendaftaran mahasiswa baru online pasti akan menanyakan asal kota/kabupaten dan provinsi dari si mahasiswa baru. Data ini tentunya dibutuhkan oleh sistem agar pilihannya dapat disajikan di formulir online-nya.

Kalau sudah bingung begini, mau tidak mau si pengembang biasanya akan mencari sendiri datanya, kemudian memasukkan data yang ditemukan ke dalam database yang mereka buat sendiri. Akibatnya, ada banyak data yang mungkin duplikat, atau mungkin salah, atau mungkin kurang lengkap, dan berbagai macam kemungkinan tidak enak lainnya.

Andaikan pemerintah punya pusat data publik yang menyimpan data-data seperti ini, tentunya masyarakat akan sangat terbantu, apalagi para pengembang peranti lunak.

Tidak hanya data seperti itu, data tentang undang-undang terbaru misalnya. Saya pribadi kalau diminta untuk mencari salinan UU ITE yang paling baru, saya akan bingung juga, karena ada banyak salinan yang berasal dari alamat-alamat yang tidak resmi seperti blog seseorang yang tidak saya kenal. Bagaimana kalau ternyata salinannya salah? Bagaimana kalau ternyata salinannya bukan yang paling baru?

Andaikan pemerintah punya pusat data publik yang menyimpan data-data seperti ini, (lagi-lagi) tentunya masyarakat akan sangat terbantu.

Dan mungkin masih banyak lagi jenis data-data yang jika disentralisasikan akan sangat berguna sekali buat khalayak ramai.

Oh iya, saya sempat menemukan artikel menarik di sini: https://github.com/blog/1657-introducing-government-github-com

GitHub adalah situs tempat penyimpanan source code tersentralisasi, yang memang namanya hanya akrab di telinga para pengembang peranti lunak. Tapi di artikel di atas, tim mereka bercerita bahwa kini GitHub bukan lagi digunakan untuk sekedar hal-hal teknis semacam itu, namun juga untuk hal-hal non-teknis seperti penyimpanan data yang berkaitan dengan hukum, peta, maupun layanan-layanan pemerintah. Indonesia juga seharusnya bisa memanfaatkan fasilitas seperti ini bukan? GitHub boleh digunakan secara gratis. :D

Lebih keren lagi, kalau misalnya pemerintah Indonesia punya sejenis API server untuk menyajikan seluruh data yang benar-benar tersentralisasi dan paling terbaru. Saya jadi ingat, kemarin sebelum pemilu berjalan, ada kompetisi untuk membuat mobile apps yang bertemakan pemilu. Hasilnya kini sudah dipublikasi di http://pemiluapps.org. Aplikasi yang dikembangkan tersebut menggunakan API Pemilu, sebuah antarmuka (interface) yang dapat digunakan oleh aplikasi untuk bertukar data. Dengan menggunakan API Pemilu ini, pengembang bisa mendapatkan data-data seperti berita terbaru terkait pemilu, social analytics untuk mengambil data dari social media, dan fungsi-fungsi lainnya. API Pemilu ini open source, dan kodenya bisa dilihat di https://github.com/pemiluAPI.

 

Yah, ini memang sebuah impian jangka panjang. Mudah-mudahan hal-hal positif seperti ini dapat cepat berkembang, dan saya bisa merasakannya sebelum saya tua. Syukur-syukur kalau saya bisa ikut mengembangkan ide ini di pemerintahan Indonesia suatu saat nanti. Siapa tahu?

Semoga bermanfaat. :)

Me-manage History Browser Dengan jQuery dan History.js Pada Halaman Web yang Menggunakan AJAX

Salah satu hal yang harus di-handle ketika menggunakan teknik AJAX adalah history di browser. Saat menggunakan AJAX untuk mengambil data di suatu alamat, proses pengambilannya dilaksanakan secara asynchronous tanpa memindahkan halaman, sehingga browser tidak mencatat history dari alamat yang pernah kita kunjungi sebelumnya. Hal ini tentu saja akan merepotkan jika nanti kita ingin mengakses suatu alamat tertentu yang telah diakses sebelumnya dan ternyata datanya diambil dengan menggunakan AJAX.

Pada kasus yang saya alami kali ini, ceritanya saya ingin membuat sebuah aplikasi web yang kira-kira kerangka tampilannya seperti ini:

Skema website yang akan dibangun.
Skema website yang akan dibangun.

Masing-masing link di menu navigasinya akan mengarah ke suatu alamat di server yang nantinya dengan menggunakan AJAX, isinya akan diletakkan di sebuah <div> yang ada di tengah halaman tersebut.

Sederhana bukan? Tapi ternyata implementasinya tidak terlalu sederhana juga. -_-

Saya mengembangkan halaman ini dengan menggunakan MVC framework untungnya, jadi tidak harus repot saat harus menangani request yang masuk ke server.

Untuk mengimplementasikan halaman ini, ceritanya saya memberikan sebuah class bernama ajax-link untuk setiap link yang akan mengakses halaman lain dengan teknik AJAX. Masing-masing link ini diberi 1 buah atribut khusus tambahan yang bernama target-element yang berisi lokasi tempat si data yang telah diambil akan diletakkan.

Ini contoh link-nya:

<a class="ajax-link" href="/site/about" target-element="div#content">Click me!</a>

Link di atas akan mengakses alamat /site/about dengan menggunakan AJAX, dan meletakkan hasilnya ke sebuah div dengan id yang bernama content.

Untuk menangani link ini, saya membuat sebuah fungsi yang akan mengambil konten dari URL yang diberikan (sourceUrl) dan kemudian menampilkannya ke tempat yang ditargetkan (targetElement):

function loadContent(sourceUrl, targetElement, callback) {

    // Fade out existing content in targetElement.
    $(targetElement).fadeOut("slow", function() {

        // Fade in loading image while downloading data.
        $("#loading").fadeIn("slow", function() {

            // Load data from the server.
            $(targetElement).load(sourceUrl, function(response, status, xhr) {
                if (status == "success") {
                    $("#loading").fadeOut("slow", function () {
                        $(targetElement).fadeIn("slow");

                        // Run the callback function if any.
                        typeof callback === 'function' && callback();
                    });
                }
                else if (status == "error") {
                    $("#loading").fadeOut("slow", function () {
                        $(targetElement).text("Error!");
                        $(targetElement).fadeIn("slow");
                    });
                }
                else {
                    // TODO: Handle unknown result.
                }
            });
        });
    });
}

Sisanya, tinggal menambahkan listener di setiap link yang memiliki class ajax-link dengan menggunakan jQuery:

$(".ajax-link").click(function() {

    // Prevent browser to do page redirection when the link is clicked.
    event.preventDefault();

    // Get the data source URL.
    var sourceUrl = $(this).attr("href");

    // Get the target element for data.
    var targetElement = $(this).attr("target-element");

    // Load content from server (the implementation is separated)
    loadContent(sourceUrl, targetElement, function() {
        // Callback function is here.
    });
});

Kode di atas sudah bisa dipakai, tapi masalahnya, setiap berpindah halaman, halaman yang telah diakses sebelumnya tidak akan tersimpan.

Setelah membaca-baca dan melakukan coba-coba, ternyata saat menggunakan AJAX, operasi terkait dengan history (termasuk tombol back dan forward harus di-handle sendiri.

Setiap browser punya operasi untuk menyimpan history saat membuka halaman web. Di setiap browser, operasi untuk menangani history bisa didapatkan dengan mengakses objek window.history. Panduan untuk memanipulasi history bisa dilihat di sini.

Pertamanya saya tidak terlalu khawatir soal history ini, tetapi kekhawatiran itu tiba-tiba timbul saat saya melihat tabel ini di halaman Mozilla Developer Network:

Setelah membaca-baca sumber lain lagi sembari googling, ternyata ada Javascript library yang bisa digunakan untuk menangani hal ini, namanya History.js.

Kekhawatiran soal isu kompatibilitas setidaknya bisa diminimalisir dengan menggunakan library ini. Dengan menggunakan History.js, fungsi untuk melakukan operasi manipulasi history telah tertanam di dalamnya dan tinggal digunakan saja.

$(document).ready(function() {

    // Initialize History.js
    var historyJs = window.History; // 'History', not 'history'.

    // Listen for click in every link that has .ajax-link class.
    $(".ajax-link").click(function() {

        // Prevent browser to do page redirection when the link is clicked.
        event.preventDefault();

        // Get the data source URL.
        var sourceUrl = $(this).attr("href");

        // Get the target element for data.
        var targetElement = $(this).attr("target-element");

        // Load content from server (the implementation is separated)
        loadContent(sourceUrl, targetElement, function() {

            // Save history.
            historyJs.pushState(null, '', sourceUrl);
        });
    });
});

Fungsi pushState yang dipanggil di bagian callback akan menyimpan URL yang sedang dibuka ke dalam history. Yap, dengan ini, fungsi history sudah berfungsi.

Ups, tapi belum selesai. Belum cukup perjuangannya. :D

Kalau kode di atas dicoba, walaupun tombol back ditekan, halaman yang ditampilkan tidak akan berubah. Itu karena fungsi untuk meng-handle tombol back di browser ketika diklik oleh pengguna belum dibuat.

Untuk menangani tombol back, sebenarnya browser memiliki event khusus bernama onpopstate yang bisa di-listen. Tetapi karena halaman ini menggunakan History.js, sebisa mungkin interaksi langsung ke implementasi browser sebaiknya dijembatani oleh library saja agar implementasinya lebih konsisten.

Jadi, untuk menangani tombol back dan forward, fungsi pushState dapat dimanfaatkan dengan lebih maksimal. Fungsi pushState membutuhkan 3 parameter: sebuah state object, judul halaman, dan URL.

Soal state object, dikutip dari Mozilla Developer Network:

  • state object — The state object is a JavaScript object which is associated with the new history entry created by pushState(). Whenever the user navigates to the new state, a popstate event is fired, and the state property of the event contains a copy of the history entry’s state object.

    The state object can be anything that can be serialized. Because Firefox saves state objects to the user’s disk so they can be restored after the user restarts the browser, we impose a size limit of 640k characters on the serialized representation of a state object. If you pass a state object whose serialized representation is larger than this to pushState(), the method will throw an exception. If you need more space than this, you’re encouraged to use sessionStorage and/or localStorage.

Untuk state object, saya menyimpan sebuah angka state counter dan target elemen dari si link yang diklik sebelumnya. Angka state counter tersebut disimpan dalam sebuah variabel global yang bernilai awal 0. Setiap kali link diklik, variabel state counter ini akan bertambah, kemudian dengan menggunakan History.js, dengan memasang fungsi bind, jika terdeteksi bahwa ada state yang berubah, secara otomatis akan dilakukan pengecekan apakah nomor state counter yang berubah telah ada sebelumnya. Jika ternyata angkanya telah ada, tentu saja artinya si pengguna telah mengklik tombol back di browser.

Implementasinya kira-kira seperti berikut:

var GLOBAL_STATE_COUNTER = 0;

$(document).ready(function() {

    // Initialize History.js
    var historyJs = window.History; // 'History', not 'history'.

    // Bind the adapter to listen 'statechange' event.
    historyJs.Adapter.bind(window, "statechange", function() {

        // Get state object.
        var state = historyJs.getState();

        // Check whether back button is pressed.
        if (state.counter < GLOBAL_STATE_COUNTER) {

            // Reload the content.
            loadContent(state.url, state.targetElement, function() {
                // Callback function is here.
            });
        }
    });

    // Listen for click in every link that has '.ajax-link' class.
    $(".ajax-link").click(function() {

        // Prevent browser to do page redirection when the link is clicked.
        event.preventDefault();

        // Get the data source URL.
        var sourceUrl = $(this).attr("href");

        // Get the target element for data.
        var targetElement = $(this).attr("target-element");

        // Load content from server (the implementation is separated)
        loadContent(sourceUrl, targetElement, function() {

            // Save history, and save the state object.
            historyJs.pushState(
               {
                   counter: GLOBAL_STATE_COUNTER,
                   targetElement: targetElement
               },
               '', // It should be filled with document title, but just ignore it for now.
               sourceUrl
            );

            // Increment global state counter.
            GLOBAL_STATE_COUNTER++;
        });
    });
});

Nah, dengan ini, tombol back dan forward-nya bisa berfungsi. ;)

Oh iya, ada beberapa catatan terkait dengan kasus ini yang rasanya penting untuk diketahui saat membangun aplikasi web yang menggunakan AJAX, untuk implementasi di sisi server-nya. Berikut beberapa hal yang saya rasa perlu diperhatikan:

Judul Halaman

Kode di atas tidak meng-handle judul yang ditampilkan di halaman web yang dibuat. Hal ini tentunya nanti harus diatur agar tampilan halamannya lebih informatif. Untuk mengubah judul halaman, pembaca tinggal mengubah atribut document.title lewat Javascript.

Menangani Request AJAX dan non-AJAX

Jika aplikasi web yang dikembangkan semakin kompleks, masing-masing alamat di server bisa jadi akan mengembalikan response yang content type-nya berbeda-beda. Data yang dikembalikan mungkin bisa saja berupa JSON, gambar, atau mungkin pecahan dari suatu halaman jika request yang masuk ternyata adalah sebuah AJAX request. Namun jika request yang masuk ternyata request biasa, sang server harus mengembalikan response yang berbeda.

AJAX request bisa diidentifikasi dari header-nya. Biasanya ada entry di header yang bernama HTTP_X_REQUESTED_WITH yang menjadi penanda bahwa request dikirimkan dari sebuah XmlHttpRequest. Javascript library pada umumnya sudah menyertakan header ini, dan sang server tinggal membacanya saja.

Untuk mengenali apakah suatu request berasal dari AJAX atau tidak, beberapa framework tertentu sudah menyediakan fungsi built-in. Di ASP.NET misalnya, sang programmer tinggal menggunakan statement Request.IsAjaxRequest() di view-nya. Di framework MVC lain seperti Laravel ada fungsi Request::ajax(), dan di CakePHP ada fungsi $this->request->is('ajax'). Implementasinya berbeda-beda, tergantung bahasa dan framework yang digunakan.

Fiuh, kira-kira demikian cerita saya tentang menangani history dengan Javascript ini. Rasanya AJAX nanti (atau mungkin sudah?) akan jadi trend untuk aplikasi web modern yang dinamis dan responsif. Karena itu, hal-hal kecil seperti ini saya rasa cukup penting untuk diketahui. Semoga bermanfaat. :D

Mempelajari Pemrograman Web

Sudah 3 tahun terakhir ini semenjak saya benar-benar ‘menjeburkan’ diri di bidang teknologi informasi dan mengawalinya dengan menjalani kuliah di program studi teknik informatika, sebagian besar aktifitas saya dihabiskan di web browser: emailblogging, menggunakan cloud computing dan banyak hal lainnya. Aplikasi desktop yang ada di komputer saya jadi banyak yang menganggur.

Kalau saat ini, aplikasi dekstop yang cukup sering saya gunakan paling hanya Microsoft Office, 7zip (untuk menangani compressed archive), beberapa IDE (NetBeans, Visual Studio), SourceTree (untuk version control system), beberapa teks editor canggih (Sublime, Notepad++) dan MuseScore (untuk menulis partitur lagu). Ada juga beberapa aplikasi yang terkait dengan sistem seperti Windows Explorer atau command prompt. Aplikasi yang selain disebutkan di atas jadi jarang sekali dipakai.

Jangan-jangan nanti semua komputer akan jadi thin client semua ya? Cukup hanya dengan web browser dan semua hal bisa dilakukan. Bisa jadi juga kan ya?

Bayangkan, kalau mau mencari video, sekarang sepertinya orang-orang lebih suka streaming di YouTube. Untuk memutar lagu, web browser sekarang juga bisa. Aplikasi web seperti SoundCloud misalnya, penuh dengan rekaman data audio yang menarik. Untuk pekerjaan kantor tidak perlu ditanya lagi. Ada Google Drive dan SkyDrive. Semuanya bisa dijalankan di web browser.

Jadi, kalau bicara masalah peluang di masa depan, saya rasa belajar web programming merupakan hal yang sangat tepat. :D

Ada yang tertarik untuk mempelajari web programming? Tulisan saya kali ini membahas tentang langkah-langkah yang bisa diikuti jika pembaca ingin mempelajari pemrograman web. ;)

Mendesain Layout Halaman Web

Pertama kali saat mempelajari hal-hal yang berkaitan dengan web, hal pertama yang harus dipahami adalah tentang Hypertext Markup Language (HTML) dan Cascading Style Sheet (CSS). HTML dan CSS merupakan gerbang pertama yang harus dipelajari untuk membuat halaman web.

Pembaca sekarang sedang melakukan browsing dengan Google Chrome atau Firefox? Coba sekarang tekan Ctrl + U.

Nah, sudah kembali ke halaman ini? :P Kode-kode panjang yang pembaca lihat setelah menekan shortcut tersebut merupakan elemen penyusun dari website yang sedang pembaca kunjungi ini.

Setiap halaman yang pembaca lihat di web browser tersusun dari struktur kode-kode HTML tersebut. Di dalamnya, bagian-bagian dari halaman tersebut diberi spesifikasi tampilan (style) dengan menggunakan CSS.

Ada banyak resources yang dapat digunakan oleh pembaca untuk mempelajari HTML. Coba saja kunjungi w3schools misalnya.

Tampilan halaman depan w3schools.

Sebenarnya, di dunia nyata, proses mendesain halaman web tidak langsung ke kode HTML dan CSS. Sebelum memutuskan untuk mengembangkan suatu halaman web, terlebih dahulu si pengembang harus memikirkan kira-kira bentuk website-nya akan seperti apa. Bentuk website tersebut pada awalnya digambar sketsanya atau biasa disebut juga wireframing. Setelah terpetakan, barulah desainer web bisa mendesain halamannya. Itupun tidak langsung menggunakan HTML dan CSS. Pada awalnya desain web tersebut hanya digambar biasa dengan software seperti Adobe Photoshop atau Illustrator.

Setelah desainnya benar-benar fix, barulah kemudian tampilan website-nya dibangun dengan HTML dan CSS.

Jika pembaca merasa sudah cukup mengerti tentang HTML dan CSS, cobalah pelajari bagaimana mengubah gambar desain menjadi halaman web yang sebenarnya. Ada banyak tutorial yang bisa pembaca cari. Biasanya saya melihat tutorial-tutorial tersebut di website-website ini: 1stwebdesigner, Tuts+, CSS-Tricks. Masih banyak website lain yang juga bagus. Googling saja. ;)

HTML 5, CSS 3, dan Lainnya

Jika pembaca sudah mulai menguasai dasar-dasar HTML, coba pelajari tentang HTML 5 dan CSS 3. Dengan 2 teknologi ini, pembaca bisa membuat sesuatu yang lebih powerful dibanding dengan HTML dan CSS biasa.  Bahkan dengan HTML 5, pembaca bisa membuat aplikasi seperti game. Selain itu jika pembaca juga mau mempelajari JavaScript, hanya dengan HTML, CSS dan JavaScript, pembaca bisa membuat aplikasi mobile. Coba lihat: PhoneGap, Steroids, dan Ionic Framework.

Mulai Mendalami Web Programming

Setelah mempelajari HTML dan CSS, langkah selanjutnya adalah mempelajari bahasa pemrograman web yang berjalan di sisi server. Ada buanyak (saking banyaknya) bahasa pemrograman yang bisa pembaca pelajari. Di antaranya ada PHP, ASP dan ASP.NET, Java, Ruby, Python dan lainnya. Pilihlah 1 bahasa dan fokuslah ke bahasa pemrograman tersebut sampai benar-benar menguasainya.

Kalau saran pribadi dari saya, pelajarilah PHP terlebih dahulu. Di antara bahasa-bahasa tersebut, PHP merupakan yang paling banyak penggunanya untuk  saat ini. Selain itu, nanti jika pembaca ingin mempunyai website sendiri misalnya, hosting di Indonesia rata-rata sudah mendukung PHP, sehingga akan lebih mudah untuk pembaca saat ingin mempraktikkan langsung hasil belajarnya.

Nanti, jika sudah menguasai PHP, berpindah ke bahasa lain tidak akan terlalu sulit. Saya pribadi bahkan tidak menganjurkan pembaca untuk langsung mempelajari Ruby, Python, dan ASP, karena bahasa-bahasa tersebut sangat strict dalam kerangka Model-View-Controller (akan saya bahas di bawah). Dengan PHP, pembaca bisa mempelajari konsep dasarnya dengan lebih mudah.

Bitnami WAMP Stack, salah satu tools yang dapat pembaca gunakan untuk mempelajari PHP web programming.
Bitnami WAMP Stack, salah satu tools yang dapat pembaca gunakan untuk mempelajari PHP web programming.

Oh iya, saat mempelajari web programming, pastikan pembaca mempelajari konsep form dengan benar. Di jagad web, yang membuat dunia di internet bisa seinteraktif seperti saat ini adalah karena adanya si tag <form> tersebut. Saat mempelajari form, pembaca pasti akan bertemu dengan terminologi seperti GET dan POST. Pelajari hal tersebut, karena disitulah nanti inti dari web programming. Jika pembaca sudah berurusan dengan form, biasanya pembaca juga akan berurusan dengan database. Pelajari pula syntax dasar dari Structured Query Language (SQL) seperti INSERT, SELECT, UPDATE dan DELETE. Pembaca akan akrab dengan 4 keywords tersebut.

Oh, satu lagi, bertahanlah dalam mempelajari programming-nya sendiri. Sebelum mempelajari hal seperti GET dan POST tadi, pembaca pasti akan berurusan terlebih dahulu dengan dasar-dasar pemrograman seperti branching (percabangan) dan looping (perulangan). Setelah itu, pembaca juga pasti akan bertemu tentang konsep function dan bahkan Object Oriented Programming. Di sinilah kesungguhan pembaca dalam mempelajari dunia komputer akan diuji. Mereka yang berhasil di tahap ini biasanya akan sukses. ;)

Nah, tentang sumber untuk belajarnya, kalau saran pribadi dari saya, cobalah cari buku atau e-book soal web programming. Sumbernya bisa banyak sekali. Untuk yang mau belajar PHP, di Google ketikkan saja php programming filetype:pdf dan pembaca akan kebanjiran dokumen PDF yang membahas tentang web programming menggunakan PHP.

Tampilan halaman it-ebooks.info, website penyedia e-book komputer gratis.
Tampilan halaman it-ebooks.info, website penyedia e-book komputer gratis.

Oh iya, satu lagi, satu lagi. :P Bertahanlah dengan banyaknya konten yang ber-Bahasa Inggris, karena Bahasa Inggris adalah lingua franca-nya para ahli komputer. Just keep learning, dan pastikan Google Translate ada di salah satu tab pembaca saat browsing. :D

Untuk memastikan bahwa pembaca benar-benar mengerti tentang web programming, cobalah membuat aplikasi web sederhana dari scratch, yakni benar-benar dari 0. Pembaca bisa membuat aplikasi blog sederhana, atau buku tamu sederhana, atau mungkin galeri foto sederhana, atau bahkan jejaring sosial sederhana? Apapun itu, cobalah membuatnya sampai benar-benar jadi. Pembaca akan lebih banyak mendapatkan ilmunya nanti, dibanding hanya sekedar membaca buku. Pastikan pembaca benar-benar mempraktikkannya ya. :)

Melompat ke Advanced Topics

Ketika pembaca merasa sudah benar-benar mengerti tentang bagaimana penggunaan HTML dan CSS, serta bagaimana mengintegrasikannya agar dapat mengirim dan mengambil data secara dinamis ke database dengan menggunakan salah satu bahasa pemrograman web, cobalah untuk melanjutkannya dengan mempelajari hal-hal berikut:

MVC Framework

Ada kalanya nanti ketika pembaca membuat 1 aplikasi web yang cukup kompleks, dan kode pembaca sudah demikian banyak, sehingga rasanya seperti berantakan sekali. Jika pembaca telah merasa demikian, ada baiknya pembaca mempelajari penggunaan MVC framework.

MVC adalah singkatan dari model-view-controllersebuah software-pattern yang memungkinkan pembaca untuk menyusun aplikasi dengan 3 objek utama yaitu model (sebagai entitas utama yang digunakan untuk mengakses data), view (sebagai tampilan yang dilihat pengguna) dan controller (sebagai pengendali utama aplikasi).

Skemanya kurang lebih bisa dilihat di gambar di bawah ini:

Tipikal kolaborasi dari komponen MVC.

Bahasa pemrograman web seperti Ruby dan ASP.NET telah menganut pattern ini di dalam fungsi utamanya. Mempelajari Ruby dan ASP.NET akan membuat pembaca merasakan langsung bentuk pattern ini.

Di PHP, ada beberapa MVC framework yang dapat pembaca gunakan, di antaranya: Yii, CakePHP, Laravel, Zend, Symfony.

Dengan menggunakan framework, aplikasi yang pembaca buat akan lebih terstruktur dan lebih mudah untuk dipelihara. Jika pembaca terjun di dunia web programming yang sebenarnya, ketika suatu aplikasi web dikembangkan oleh banyak programmer, barulah nanti akan terasa bahwa menggunakan framework yang telah ada atau setidaknya menggunakan pattern MVC akan mempermudah pengembang untuk terus memperbarui aplikasinya.

CakePHP, salah satu PHP MVC framework.
CakePHP, salah satu PHP MVC framework.

Javascript dan AJAX

Pembaca pernah melihat website yang di halaman depannya ada slideshow gambar, atau ada efek-efek transisi atau mungkin efek bergerak yang menarik? Nah, disitulah peran Javascript.

Javascript adalah sebuah bahasa pemrograman dynamic yang berjalan di sisi client dan merupakan bagian dari web browser yang pembaca pakai. Dengan menggunakan Javascript, pembaca bisa memodifikasi elemen-elemen  (Document Object Model atau DOM) halaman web secara langsung dan berinteraksi dengan pengguna dengan konten yang interaktif. Mempelajari Javascript akan membantu pembaca untuk memperkaya user experience dari halaman web yang pembaca kembangkan.

Jika pembaca ingin mempelajari dasar-dasar dari Javascript, pembaca bisa mempelajarinya secara interaktif di Codecademy. Di sana nanti pembaca akan mendapatkan instruksi-instruksi yang bisa pembaca ikuti untuk mendalami Javascript.

Jika pembaca sudah mulai menguasainya, cobalah mencoba-coba kode Javascript yang pembaca pelajari dengan meletakkannya langsung di halaman web sebagai latihan.

Nah, setelah merasa sudah mulai menguasai Javascript, pembaca bisa mencoba Javascript library seperti jQuery misalnya. Dengan menggunakan library, pembaca bisa melakukan banyak aksi-aksi ataupun menambahkan efek-efek tertentu tanpa harus membuatnya dari awal.

Halaman depan website jQuery.
Halaman depan website jQuery.

Di Javascript, ada sebuah teknik menarik yang disebut AJAX. AJAX merupakan singkatan dari Asynchronous Javascript and XML, yaitu sebuah teknik untuk menciptakan aplikasi web yang responsif. Dengan menggunakan AJAX, pengguna halaman web tidak perlu berpindah dan me-load halaman dari awal, karena segala sesuatunya telah dilakukan dibelakang pengguna secara asynchronous tanpa pengguna sadari.

Dengan menggunakan AJAX, website akan terasa lebih responsif dan interaktif di mata pengguna. SoundCloud, Facebook dan Twitter adalah contoh aplikasi yang menggunakan AJAX. Saat mengetikkan komentar di salah satu posting di Facebook misalnya, pembaca cukup mengetikkan komentar dan menekan enter, dan tahu-tahu komentar pembaca sudah ditampilkan di sana bukan? Sebenarnya, tanpa disadari, saat penggunanya menekan enter setelah mengetik komentar, sang Facebook di belakang layar melakukan pengiriman data ke server dan langsung menampilkannya tanpa harus berpindah halaman.  Seperti itulah contoh pemanfaatan AJAX. Kalau pembaca sudah menguasai jQuery, melakukan AJAX tidak akan menjadi pekerjaan sulit.

MV* Framework Dengan Javascript

Beberapa aplikasi web, ada yang sebagian besar kodenya merupakan kode Javascript. Biasanya, aplikasi yang didesain hanya berkutat di 1 halaman (disebut juga single page application atau disingkat SPA) akan mengalaminya. Saat sebagian besar aksi perpindahan halaman harus ditentukan dengan menggunakan Javascript, tentu kode Javascript yang ada akan menjadi banyak dan biasanya tidak terstruktur, sama kasusnya seperti kasus MVC pada bahasa pemrograman web seperti PHP yang kita bahas sebelumnya di atas.

Untuk mengatasi hal ini, konsep MVC pun juga dianut dalam pemrograman Javascript, hanya saja yang dipakai adalah konsep turunannya, dan ada banyak sebutan dari turunan pattern MVC ini. Ada yang menyebutnya MVVM (model-view-view model), ada juga yang menyebutnya MVP (model-view-presentation). Karena itu, biasanya turunan-turunan dari MVC ini disingkat menjadi MV*.

Ada banyak MV* framework ini dan tentunya semuanya diprogram dengan Javascript. Di antaranya ada: AngularJS, Backbone.js, Knockout.js, dan Ember.jsFramework-framework ini sudah banyak digunakan di berbagai aplikasi-aplikasi yang besar. Framework Backbone.js saja sudah dipakai di aplikasi seperti WordPress, Four Square dan SoundCloud (coba lihat di sini).

Halaman depan website AngularJS.
Halaman depan website AngularJS.

Demikianlah kira-kira langkah-langkah yang dapat diikuti untuk mempelajari pemrograman web. Tulisan ini kurang lebih bersumber dari pengalaman pribadi saya juga, hehe. Pada akhirnya, siapapun orangnya dan bagaimanapun caranya saat mempelajari web programming pasti akan berhadapan dengan beberapa atau mungkin semua hal yang saya bahas di tulisan ini. Jika ada pembaca yang ingin menambahkan, memberi saran atau mengkritik terkait tulisan ini, silakan disampaikan lewat komentar, dan akan saya terima dengan tangan terbuka.

Mempelajari sesuatu merupakan tantangan yang besar, dan ketika berhasil pasti akan sangat menyenangkan rasanya. Mudah-mudahan pembaca yang ingin mempelajari web programming bisa dipermudah dengan adanya tulisan ini. Semoga bermanfaat. :D

Menangani Penyimpanan File yang di-Upload ke Server

Dalam pembuatan aplikasi web, terkadang dibutuhkan suatu skenario untuk meng-upload satu atau beberapa file ke server. Untuk mengganti gambar profil di aplikasi jejaring sosial misalnya, pengguna pasti akan berurusan dengan skenario ini.

Proses meng-upload file pada aplikasi web ditangani oleh masing-masing infrastruktur dari aplikasi web yang digunakan, namun hampir seluruh urutan prosesnya sama: user akan memilih file, aplikasi web akan menyimpan file yang di-upload oleh user ke suatu path dengan nama file tertentu, kemudian jika dibutuhkan informasi file tersebut akan disimpan di database. Hal yang sering menjadi masalah adalah tentang metode menyimpan file-file tersebut.

Tulisan saya kali ini membahas beberapa cara yang bisa dilakukan untuk menangani penyimpanan file yang di-upload ke server lewat aplikasi web.

Cara 1: Simpan File Apa Adanya

Menyimpan file apa adanya adalah cara yang paling mudah dan juga paling tidak direkomendasikan. -_- Simpan file yang telah di-upload ke suatu direktori tertentu dengan nama yang sama persis saat di-upload.

Misalkan, ada seseorang bernama Budi yang menyimpan foto profil di komputernya dengan nama budi.jpg, maka aplikasi akan meng-upload dan menyimpannya juga dengan nama budi.jpg di suatu direktori di server.

Masalahnya akan muncul, jika ternyata ada Budi lain (sebut saja Budi 2) yang juga menyimpan foto profil dengan nama budi.jpgFile yang sama tentu saja akan tertimpa.

Jika hal seperti ini terjadi, tentu saja gambar foto profil Budi 1 dan Budi 2 akan selalu sama. Sedangkan di Indonesia mungkin ada ribuan orang dengan nama Budi (Budi 3, Budi 4, dan seterusnya). Dengan cara ini, gambar foto profil ribuan orang ini pasti akan selalu sama jika mereka meng-upload file dengan nama budi.jpg. Bayangkan saja, mereka akan saling berebut berganti gambar profil bukan? :P

Cara ini hanya untuk ilustrasi kemungkinan terburuk saja. Sebisa mungkin hindari cara sederhana ini, kecuali jika dapat dipastikan bahwa tiap user akan meng-upload file yang namanya pasti unik.

Cara 2: Simpan File di Dalam Database

Banyak Database Management System (DBMS) yang menyediakan tipe data binary untuk dapat menyimpan file langsung di simpan di dalam database. Tipe data binary large object (BLOB) di MySQL misalnya, dengan menggunakan tipe data ini, file yang di-upload oleh user dapat langsung di simpan di database dengan statement INSERT seperti biasa.

Namun sebaiknya sebelum menggunakan cara ini, pelajari tentang efek penyimpanan binary file  di dalam database terhadap performa dari DBMS yang digunakan, karena ada catatan tertentu terkait soal penggunaan cara ini.

Sebagai contoh, untuk pengguna DBMS MySQL, coba lihat halaman ini: http://stackoverflow.com/questions/5285857/when-is-using-mysql-blob-recommended

Cara 3: Simpan File di Direktori Tertentu Dengan Nama Khusus

Cara ketiga yang cukup mudah dan paling umum adalah menyimpan file tersebut dengan suatu nama khusus tertentu. Untuk cara ini, ada beberapa cara yang bisa dilakukan.

Contoh sederhana misalnya, aplikasi bisa saja menyimpan file yang telah di-upload tersebut dengan format nama tertentu. Sang programmer dapat membuat prosedur sedemikian sehingga setiap file yang di-upload akan disimpan dengan nama file-n.extension di mana n adalah urutan upload -nya. Jadi nanti di dalam direktori tempat file upload akan ada file-1.extension, file-2.extension dan seterusnya. Sedangkan informasi file yang aslinya bisa disimpan di dalam database.

Kelemahan metode ini adalah, sang programmer harus memikirkan sebuah fungsi untuk meng-generate format nama ini dengan benar tanpa kemungkinan adanya saling timpa.

Cara lain bisa juga dengan cara meng-generate sejenis random characters tertentu yang nantinya akan digunakan sebagai nama file. Dengan cara ini, sang programmer tinggal memikirkan 1 fungsi untuk menghasilkan karakter acak yang stabil untuk nama file yang akan disimpan.

Ngomong-ngomong soal karakter acak, ada beberapa cara yang bisa dilakukan. Di antaranya, sang programmer bisa menggunakan fungsi untuk meng-generate sebuah Universally Unique Identifier. Banyak bahasa pemrograman yang sudah memiliki built-in function untuk melakukan hal ini.

Ini contoh UUID: 88961191-5ad3-49b2-be97-c3f481820644. Spesifikasinya diatur dalam RFC 4122.

Banyak metode untuk menghasilkan karakter acak. Biasanya, dengan menggunakan parameter timestamp, keunikan karakter bisa dijamin. Membungkus string angka timestamp dengan fungsi md5 misalnya, itu sudah cukup menghasilkan karakter yang lumayan acak (lihat fungsi PHP di bawah sebagai contoh).

$randomCharacters = md5(strtotime("now"));

Untuk fungsi yang lebih reliabel, bisa juga menggunakan fungsi checksum untuk file. Fungsi checksum akan menghasilkan serentetan string yang unik dan tentunya dapat digunakan untuk nama file yang di-upload. Hasil checksum bisa dikatakan sebagai sidik jari dari suatu file sehingga terjamin keunikannya.

Algoritma checksum ada banyak pilihannya, dan sama seperti UUID tadi, fungsi built-in-nya juga sudah banyak di berbagai macam bahasa pemrograman. Tinggal dipakai saja.

Cara 4: Simpan File di Dalam Struktur Direktori Tertentu Dengan Nama Khusus

Cara nomor 3 di atas, boleh dipakai dengan catatan: jumlah file dalam direktori tempat penyimpanan file yang di-upload tidak terlalu banyak.

Saat mengakses suatu direktori dengan menggunakan perintah ls di Linux atau dir di Windows, terlebih dahulu, sistem harus melakukan pendataan terhadap isi direktori. Itulah mengapa saat menggunakan file explorer di semua sistem operasi, semakin banyak menyimpan file di dalam direktori maka akan semakin lama proses loading-nya.

Selain itu, setiap disk tempat penyimpanan data memiliki batas maksimum jumlah file yang dapat disimpan di dalam 1 direktori. Batas maksimum ini dipengaruhi oleh jenis file system yang digunakan (lihat tabel di bawah).

Sistem Operasi File System Jumlah File Maksimum di 1 Direktori
Windows FAT-32 268,173,300
NTFS 4,294,967,295 (232-1)
Linux ext3 Tergantung Kapasitas Disk
ext4 Tergantung Kapasitas Disk
Mac OS HFS 65,535
HFS+ 4,294,967,295 (232-1)

Diambil dari banyak sumber. Jika ada yang keliru mohon beri pemberitahuan pada penulis.

Jika aplikasi web yang dikembangkan akan menghasilkan banyak sekali file yang di-upload seperti aplikasi penyimpanan gambar, faktor ini harus sangat diperhatikan.

Untuk menangani hal ini, diantaranya, sang programmer dapat memisahkan file-file yang di-upload ke dalam klasifikasi-klasifikasi yang lebih spesifik dalam bentuk direktori. Misalnya, jika file yang di-upload diletakkan di direktori upload/, maka jika ada user yang bernama imamfile-nya bisa diletakkan di direktori upload/imam/.

Klasifikasi yang dilakukan dapat dipilih sesuai kebutuhan. Direktori klasifikasi bisa saja dibuat berdasarkan parameter tertentu. Sebagai contoh, aplikasi WordPress menyimpan file yang di-upload di direktori wp-content/uploads/, dan kemudian diklasifikasikan berdasarkan tahun, dan di dalamnya diklasifikasikan lagi berdasarkan bulan.

Ada banyak skenario lain yang mungkin lebih advanced dalam menangani penyimpanan file yang di-upload. Tulisan ini hanya membahas beberapa diantaranya. Demikianlah kira-kira sekelumit cara yang dapat dilakukan untuk menyimpan file yang di-upload oleh user ke dalam server. Semoga bermanfaat. :)

Mengatasi Isu Cross-Origin Resource Sharing (CORS)

Ceritanya kemarin saya sedang mengembangkan sebuah aplikasi web bersama teman-teman seangkatan saya. Saya kebagian in charge di tim back end. Saat itu saya sedang mengerjakan halaman “Tentang Kami” yang berisi profil-profil anggota tim pengembang.

Aplikasi ini dikembangkan dengan menggunakan WordPress. Kebetulan, profil user di WordPress ditangani oleh Globally Recognized Avatars (Gravatar) yang berarti tentunya, detail profil user yang ada seperti foto, facebook, twitter dan lainnya harus di-fetch dari situs Gravatar tersebut.

Syukurnya, Gravatar punya API yang dapat digunakan oleh publik. Jadi saya gunakan saja API tersebut untuk mengambil data.

about-us-page
Tampilan halaman “Tentang Kami” yang sedang dikerjakan.

Sebagai informasi, jumlah tim kami ada 11 orang, dengan kata lain saya harus melakukan perulangan 11 kali untuk mengambil data profil dari situs tersebut. Belum lagi untuk menampilkan profil kontributor yang nanti jumlahnya bisa banyak. Pengambilan data akan dilakukan dengan menggunakan PHP biasa. Jadi, implementasinya waktu itu seperti ini:

foreach ($users as $user) {
    $str = file_get_contents( 'http://www.gravatar.com/' . md5($user->user_email) . '.php' );
    $profile = unserialize( $str );
    if ( is_array( $profile ) && isset( $profile['entry'] ) )
        /* Action to display profile... */
}

Saat dicoba, ternyata proses loading-nya lama sekali. -_- Saya baru sadar, proses pengambilan data oleh PHP dilakukan secara berurut. Dengan kata lain, profil si user akan diambil satu-satu, dan prosesnya harus ditunggu sampai selesai baru bisa mengambil profil lainnya. Kalau misalnya ada masalah di koneksi pada saat melakukan fetching salah satu profile, tentu saja semuanya jadi ikut bermasalah. Belum lagi kalau misalnya nanti jumlah user yang ada menjadi lebih banyak seiring berjalannya waktu. Mau berapa lama loading-nya?

Karena itu, supaya aman, proses fetching informasi profile dari Gravatar harus dilakukan secara paralel. Masalahnya, PHP tidak mendukung multithread secara default. Jadi, bagaimana?

Tentu saja, JavaScript!

Dengan menggunakan jQuery, profilnya akan diambil secara asynchronous, jadi tampilan halaman akan muncul terlebih dahulu, baru kemudian profilnya akan di-append satu-satu ke halaman tersebut. Untungnya Gravatar menyediakan API yang dapat digunakan untuk mengambil data dalam format JSON. Kodenya jadi begini:

$(document).ready(function() {
    $.get('http://www.gravatar.com/' + userMd5Hash + '.json', function(data) {
        /* Operation to parse JSON (emitted). */
        $("#" + userMd5Hash + "-accounts").append(/* ... */);
    });
});

Saat dicoba dijalankan, tiba-tiba saya mendapatkan pesan error di jendela console. Tampilannya mirip seperti di bawah ini:

cors-error

Nah, ada apa lagi ini? -_-

Ternyata, operasi GET menggunakan AJAX dengan menggunakan jQuery yang saya lakukan terbentur oleh same origin policy. Ini ada apa lagi ya? o.O

Ternyata..

Jadi, saya mengerjakan halaman ini di localhost, sedangkan profil yang ingin saya ambil, ada di alamat domain gravatar.com yang tentunya berbeda lokasinya. Secara defaultweb browser tidak mengizinkan langsung operasi pengambilan data yang berbeda domain seperti ini untuk alasan keamanan.

Setelah googling beberapa saat, ternyata untuk mengatasinya, harus dilakukan penyetelan yang memungkinkan untuk melakukan Cross-Origin Resource Sharing (CORS). Untuk melakukannya, ada 2 pilihan yang dapat dilakukan:

Enable CORS di Server Tujuan

Untuk dapat melakukan CORS, pemilik server harus menambahkan header khusus di setiap response yang dikembalikan dari tiap request yang diberikan yaitu:

Access-Control-Allow-Origin: *

Jika header ini tidak didapatkan di response yang dikirimkan balik, maka browser akan memberikan pesan error seperti yang ada di atas tadi.

API di website lain seperti GitHub misalnya, sudah mengizinkan CORS secara default (lihat gambar di bawah, dan perhatikan kotak merah):

github-response-header

Sedangkan, Gravatar tidak mengizinkannya (lihat gambar di bawah):

gravatar-response-header

Karena saya tidak mungkin mengotak-atik API server milik Gravatar, ya apa boleh buat. -_- Tapi untungnya, di sisi client ada hal lain yang dapat dilakukan, yaitu:

Gunakan JSON with padding (JSONP)

Teknik yang dapat dilakukan untuk mengatasi ini adalah menggunakan JSONP. Implementasinya, cukup dengan mengganti rutin jQuery yang digunakan, dan mengubah URL request dengan menambahkan parameter callback.

$(document).ready(function() {
    $.getJSON('http://www.gravatar.com/' + userMd5Hash + '.json?callback=?', function(data) {
        /* Operation to parse JSON (emitted). */
        $("#" + userMd5Hash + "-accounts").append(/* ... */);
    });
});

Fiuh, dan akhirnya berhasil juga. :D

Syukur sekali saya mendapatkan masalah ini. Kebetulan, aplikasi yang sedang saya kerjakan dan skripsi saya saat ini banyak berhubungan dengan RESTful API, dan isu seperti CORS seperti ini pasti akan sangat membingungkan nanti untuk orang yang menggunakan API yang saya kembangkan. Jadi, untuk pengembang REST API, sepertinya isu CORS seperti ini patut untuk diperhatikan.

Demikian cerita ini, mudah-mudahan bermanfaat untuk pembaca ya. :)