JSONP Dengan Javascript dan jQuery – Lintas Domain

Setelah sebelumnya kita bahas tentang request data JSON pada domain yang sama, pada kesempatan kali ini kita akan membahas penerpan JSONP pada Javascript dan jQuery pada domain yang berbeda (lintas domain).

Pembahasan pada artikel ini terkait penggunaan JSON pada Javascript, untuk itu sebelum lanjut pastikan sobat sudah membaca artikel:  JSON Pada Javascript – Panduan Lengkap.

Artikel tersebut membahas lengkap apa dan bagaimana JSON pada Javascript.

I. Batasan Same Origin Policy

Jika json berasal dari domain yang sama, maka akan dengan mudah kita mengambilnya, namun jika berada pada domain yang berbeda maka akan sedikit ribet.

Kenapa?

Karena kita TIDAK DAPAT mengambil data tersebut melalui ajax  atau objek XMLHttpRequest,  hal ini sebenarnya tidak hanya berlaku untuk data JSON, melainkan semua data dari domain berbeda.

Kenapa demikian?

Karena ada batasan “same origin policy”, yang artinya script hanya diperbolehkan mengakses data pada origin (sumber) yang sama, yang meliputi: (1) protokol (http/https) yang sama, (2) domain yang sama, dan (3) port yang sama, hal ini sudah disepakati bersama dan diterapkan oleh semua browser.

Same origin policy di terapkan untuk alasan keamanan, misal: jika kita membukan e-banking, kemudian di tab yang lain kita membuka web yang mengandung script jahat, maka script tersebut akan leluasa mengakses halaman e-banking kita.

Seperti apa batasan same origin policy ini? perhatikan contoh berikut:

$.ajax({
  url: 'http://webdevzoom.com/wp-content/demo/last_article/',
  dataType: 'json',
  success: function(data) {
    console.log(data);
  },
  error: function(xhr, status, msg) {
    console.log('Status: ' + status + "\n" + msg);
  }
})

Pada contoh diatas, kita mengambil 5 artikel terbaru dari webdevzoom.com. Jika script dijalankan, kita akan mendapati error:

Same Origin Policy Error

Same Origin Policy Error

II. Memperkenalkan JSONP

Untuk mengatasi batasan same origin policy, pada json, kita dapat menggunakan jsonp (json dengan padding).

Cara ini sebenarnya cara lama, saat ini sudah ada metode yang lebih baru yaitu  CrossOrigin  Resource Sharing (CORS) dimana kita cukup menambahkan “Allow Origin” pada HTTP header maka domain lain dapat mengakses resource kita.

Namun, jsonp masih populer dan masih relevan untuk digunakan, sehingga tidak ada salahnya kita bahas disini.

Apa itu JSONP?

JSONP ini sebenarnya berupa eksekusi dari fungsi javascript, sehingga bentuk nya adalah nama_fungsi(...)  misal:

function json_data(obj) {
  alert (obj.website);
}

// inilah bentuk JSONP
json_data({"website":"Jagowebdev.com"});

Dari contoh diatas, terlihat jelas bahwa JSONP ini berbentuk eksekusi dari fungsi dengan argumen berisi data JSON. Nah, karena merupakan eksekusi fungsi javascript, maka kita harus meletakkannya di tag <script>

Untuk lebih memahami JSONP, perhatikan contoh berikut:

Misal:

1. Saya letakkan JSONP diatas di domain webdevzom.com dengan nama file jsonp-plain.php dengan content:

json_data({"website":"Jagowebdev.com"});

2. Selanjutnya di domain jagowebdev.com saya buat file json-remote-jsonp-plain.html  sebagai berikut:

<html>
<head>
  <title>Belajar JSONP</title>
  <script>
    function json_data(obj) {
      alert(obj.website);
    }
  </script>
  <script src="http://webdevzoom.com/wp-content/demo/json-pada-javascript/jsonp-static.php"></script>
</head>
<body>
</body>
</html>

Jika file tersebut dijalankan, maka hasil yang kita peroleh adalah:

Mengambil Data JSONP Dengan Javascript

Mengambil Data JSONP Dengan Javascript

Demo:  json-remote-jsonp-plain.html

Pada contoh diatas, setelah <script> mengambil data dari http://webdevzoom.com/wp-content/demo/json-pada-javascript/jsonp-static.php, <script> langsung mengeksekusi data tersebut dengan menjalankan fungsi json_data()

Jika fungsi tidak ditemukan, maka akan muncul pesan error, misal kita ganti data jsonp pada file  jsonp-static.php menjadi  custom_function({"website":"Jagowebdev.com"}) maka ketika url dijalankan, kita akan mendapati pesan error sebagai berikut:

JSONP Error - Fungsi Tidak Ditemukan

JSONP Error – Fungsi Tidak Ditemukan

Pesan error tersebut dikarenakan script mencari fungsi custom_function() namun tidak ditemukan.

Menggunakan Fungsi Dinamis – Callback Dinamis

Pada pembahasan sebelumnya kita ketahui bahwa jsonp adalah eksekusi dari sebuah fungsi,  yang pada contoh sebelumnya, nama fungsinya adalah json_data()

Dalam praktik, nama fungsi ini dapat berubah ubah (dinamis) tergantung query string  yang ada di url, yang umumnya menggunakan query string dengan nama callback.

Misal: jika fungsi yang akan dieksekusi adalah my_function(), maka urlnya adalah:

http://webdevzoom.com/wp-content/demo/json-pada-javascript/jsonp-dynamic.php?callback=my_function

Nah agar nama fungsi dapat berubah ubah (dinamis), kita perlu  membuat kondisi sesuai dengan value dari callback.

Misal pada webdevzoom.com saya buat file jsonp-dynamic.php dengan script sebagai berikut:

<?php
$json = '{"website":"Jagowebdev.com"}';
if (@$_GET['callback'])
  echo @$_GET['callback'] . '(' . $json . ')';
else
  echo $json;

Pada script diatas, jika url mengandung query string callback, maka yang dihasilkan adalah jsonp, sebaliknya jika tidak maka bentuknya json biasa:

Penggunaan callback dinamis ini wajib, terutama jika data di share ke public sehingga mereka bebas menggunakan nama fungsi, tidak perlu repot repot bertanya ke kita 😀 atau repot-repot membaca dokumentasi.

dan juga… jika kita menggunakan JQuery, maka disarankan menggunakan callback dinamis, kita bahas di bagian bawah ya…

Berikut ini contoh menggunakan callback dinamis:

<html>
<head>
  <title>Belajar JSONP</title>
  <script>
    function custom_function(obj) {
      alert(obj.website);
    }
  </script>
  <script src="http://webdevzoom.com/wp-content/demo/json-pada-javascript/jsonp-dynamic.php?callback=custom_function"></script>
</head>
<body>
</body>
</html>

Ketika script tersebut dijalankan, hasil yang kita peroleh sama seperti contoh sebelumnya yaitu alert yang berisi teks Jagowebdev.com

Demo: json-remote-jsonp-dinamis.html

III. JSONP Dengan JQuery

Setelah kita mengetahui bagaimana cara kerja jsonp, selanjutnya kita bahas penerapannya pada jQuery.

Seperti kita ketahui, sebenarnya tujuan kita adalah mendapatkan data JSON saja, iya kan? cuman gara-gara ada batasan same origin policy, kita perlu jalan memutar menggunakan JSONP

Nah, jika kita menggunakan jQuery, jalan memutar tersebut akan dikerjakan oleh JQuery dibelakang layar, sehingga kita dapat langsung memperoleh objek javascriptnya.

1. Callback Dinamis

Terdapat berbagai cara penerapan jsonp pada Jquery, intinya kita tentukan apakah menggunakan callback dinamis atau statis.

Untuk callback dinamis, kita tidak perlu mendefinisikan property callback di method  $.ajax, sehingga penulisan menjadi lebih simpel, misal:

$.ajax({
  url: 'http://webdevzoom.com/wp-content/demo/json-pada-javascript/jsonp-dynamic.php',
  dataType: 'jsonp',
  success: function(obj) {
    // Berupa objek javascript
    alert(obj.website);
  },
  error: function(xhr, status, msg) {
    console.log('Status: ' + status + "\n" + msg);
  }
})

Demo: jquery-callback-dinamis.html

Perhatikan bahwa pada script diatas, pada property  dataType, Kita menggunakan jsonp bukan json.

Jika script tersebut dijalankan, maka hasil yang kita peroleh sama seperti pada contoh sebelumnya yaitu berupa alert “Jagowebdev.com”

Pada contoh diatas, secara otomatis Jquery akan menambahkan query string callback pada request yang kita buat dan nama callback random (acak), perhatikan gambar berikut:

JSONP Dengan jQuery - Callback Dinamis

JSONP Dengan jQuery – Callback Dinamis

Karena callback dinamis, maka jika callback kita buat statis, maka akan muncul pesan error, misal jika url ajax kita ubah menjadi http://webdevzoom.com/wp-content/demo/json-pada-javascript/jsonp-static.php maka kita akan mendapati error sebagai berikut:

JSONP Dengan jQuery - Error Fungsi Tidak Ditemukan

JSONP Dengan jQuery – Error Fungsi Tidak Ditemukan

Pada gambar diatas terlihat bahwa jQuery menambahkan query string callback dengan nama callback=jQuery33101651155002595679_1523147140900 dan menyediakan fungsi dengan nama tersebut.

Namun,  karena jsonp  pada url diatas menghasilkan fungsi statis yaitu json_data() maka fungsi tersebut gagal dieksekusi.

2. Callback Statis

Selain callback dinamis, untuk keperluan tertentu kita perlu untuk menggunakan callback statis (misal ketika menggunakan api pada flickr).

Pada jQuery kita dapat mendefinisikan sendiri nama callback, yaitu dengan menambahkan property jsonpCallback pada method ajax, sebagai contoh:

function json_data(obj) {
 alert(obj.website);
}

$.ajax({
  url: 'http://webdevzoom.com/wp-content/demo/json-pada-javascript/jsonp-static.php',
  dataType: 'jsonp',
  jsonpCallback: 'json_data',
  error: function(xhr, status, msg) {
    console.log('Status: ' + status + "\n" + msg);
  }
})

Pada script diatas kita memberi nama callback dengan json_data karena kita tahu bahwa pada url yang kita panggil, menghasilkan jsonp  dengan fungsi json_data()

Jika script tersebut dijalankan, maka jQuery akan menambahkan query string json_data pada url.

Note.. Perhatikan juga bahwa pada script diatas, kita tidak menggunakan property success pada method ajax, kenapa? karena data JSON akan otomatis diarahkan ke fungsi json_data()

Namun, kita juga dapat menggunakan property success untuk mengolah data json tersebut, contoh:

function json_data(obj) {
 alert(obj.website);
}

$.ajax({
  url: 'http://webdevzoom.com/wp-content/demo/json-pada-javascript/jsonp-static.php',
  dataType: 'jsonp',
  jsonpCallback: 'json_data',
  success: function (obj) {
    alert(obj.website);
  },
  error: function(xhr, status, msg) {
    console.log('Status: ' + status + "\n" + msg);
  }
})
Pada kondisi tertentu, ketika menggunakan callback statis, fungsi callback tidak tereksekusi sehingga script didalamnya tidak berjalan, sebagai solusinya kita gunakan property success untuk mengolah data json

IV. JSON di Berbagai Website

Dalam praktik, berbagai web menyedikan berbagai bentuk JSON, namun tidak semunya bisa kita akses menggunakan request jsonp, untuk itu pastikan remote domain mensupport jsonp, misal dengan menambahkan callback pada query string.

1. JSONP Pada Github.com

Sebagai contoh, github telah menyediakan api untuk mengambil detail data user yang terdaftar.

Untuk mengakses data tersbeut, format url yang digunakan adalah  https://api.github.com/users/nama_user

Misal kita ambil data user Taylor Otwell (founder framework Laravel) maka url yang digunakan adalah:  https://api.github.com/users/taylorotwell

Jika kita jalankan url diatas menggunakan browser, maka hasil yang kita peroleh adalah data JSON biasa

Jika tambahkan callback, misal  https://api.github.com/users/taylorotwell?callback=custom_function maka yang kita peroleh adalah data json sebagai berikut:

custom_function({
  "meta": {
    "Content-Type": "application/javascript; charset=utf-8",
    ...
  },
  "data": {
   "login": "taylorotwell",
   ...
  }
})

Dari data diatas terlihat bahwa format data  adalah JSONP, sehingga kita bisa mengambil data tersebut menggunakan jsonp, sebagaimana telah  kita bahas pada bagian IV.

Demo:  json-remote.php

2. JSONP Pada Flickr.com

Contoh lain adalah data flickr, salah satu media yang populer untuk berbagi foto.

Flickr menyediakan api url yang memungkinkan kita untuk mendapatkan data foto yang diupload user, format url yang digunakan adalah https://api.flickr.com/services/feeds/photos_public.gne

Ketika url tersebut dijalankan di browser, kita akan mendapatkan data dengan format XML.

Selain XML, flickr juga menyediakan data dengan format json, yaitu dengan menambahkan query string format=json, sehingga url menjadi:  https://api.flickr.com/services/feeds/photos_public.gne?format=json

Jika kita jalankan url tersebut, maka kita akan langsung mendapatkan data dengan format jsonp dengan nama fungsi  jsonFlickrFeed()

Contoh: ketika kita jalankan url  https://api.flickr.com/services/feeds/photos_public.gne&tags=nature&format=json kita dapatkan hasil:

jsonFlickrFeed({
  "title": "Recent Uploads tagged nature",
  "link": "https://www.flickr.com/photos/tags/nature/",
  ...data lain...
  "items": [
    {
      "title": "folded texture",
      "link": "https://www.flickr.com/photos/gnarlydog/27437163808/",
      "media": {
        "m": "https://farm1.staticflickr.com/808/27437163808_eb7d9f2341_m.jpg"
      },
      "date_taken": "2018-04-01T06:32:10-08:00",
      ...data lain...
    },
    ...data lain...
  ]
})

Untuk dapat menggunakan data tersebut, maka kita harus menyediakan fungsi dengan nama  jsonFlickrFeed(), sebagai contoh:

function jsonFlickrFeed() {}

$.ajax({
  url: url_user, 
  dataType: 'jsonp',
  jsonpCallback: 'jsonFlickrFeed',
  success: function(obj) {
    // Some Code
  },
   error: function(xhr, status, msg) {
    console.log('Status: ' + status + "\n" + msg);
  }
})

Note…  Pada script diatas, script untuk mengolah data json saya tulis pada properties success: function(obj) bukan di fungsi jsonFlickerFeed(), fungsi terebut hanya untuk menggugurkan kewajiban untuk menuliskan fungsi.

DEMO: json-remote-flickr.php

Menampilkan Foto Dari Flickr Dengan jQuery

Menampilkan Foto Dari Flickr Dengan jQuery

Note.. pada demo diatas, script agak kompleks karena saya sertakan kode untuk lazy load image dan layout masonry (untuk tampilan wide) sehingga tampilan lebih rapi dan menarik.

Callback dinamis pada Flickr.com

Flickr.com juga meyediakan callback dinamis dengan menambahkan query string  jsoncallback, sehingga misal untuk mendapatkan nama fungsi custom_function(), url yang kita tulis:

https://api.flickr.com/services/feeds/photos_public.gne?tags=nature&format=json&jsoncallback=custom_function

Dengan callback dinamis ini, maka kita tidak perlu menuliskan fungsi:  jsonFlickrFeed(), sebagai latihan, silakan dicoba di terapkan di jQuery.

3. JSON Pada Medium.com –  Bukan JSONP

Tidak semua web support JSONP, misal pada web medium.com, kita dapat mengambil posting terakhir dari user tertentu  dalam bentuk data JSON dengan url sebagai berikut:  https://medium.com/@steve.yegge/latest?format=json.

Format JSON yang dihasilkan berupa JSON biasa bukan JSONP, dengan demikian kita tidak dapat menggunakan javascript secara langsung, melainkan harus melalui proxy (perantara) – kita bahas di artikel lain.

V.  Kesimpulan

Pada origin yang berbeda (domain yang berbeda), data JSON dapat mudah diperoleh jika berbentuk JSONP.

Pengaturan bentuk JSONP ini dapat mudah dilakukan jika kita memiliki kontrol pada website tersebut, atau memang dengan sengaja website tersebut menyediakan data jsonp.

Namun, jika web tersebut tidak mensupport jsonp dan kita tidak memiliki kontrol pada  website tersebut, maka masalah akan menjadi rumit karena kita tidak bisa secara langsung menggunakan javascript melainkan harus menggunakan perantara(proxy).

Demikian pembahasan tentang json pada javascript pada domain yang berbeda. semoga bermanfaat.

Subscibe Now

Suka dengan artikel di Jagowebdev.com? jangan sampai ketinggalan, segera join ke milis kami untuk update informasi terbaru dari Jagowebdev.com

Komitmen Kami: Kami senantiasa menghargai privasi Anda dan tidak akan membagikan identitas Anda ke pihak manapun.

Silakan tinggalkan komentar

Newsletter

Jadilah yang pertama tahu berita terbaru dari Jagowebdev.com