TL; DR
JSONP adalah trik lama yang diciptakan untuk melewati pembatasan keamanan yang melarang kita untuk mendapatkan data JSON dari server yang berbeda ( asal yang berbeda * ).
Caranya bekerja dengan menggunakan <script>
tag yang meminta JSON dari tempat itu, misalnya { "user":"Smith" }
:, tetapi dibungkus dengan fungsi, JSONP yang sebenarnya ("JSON with Padding"):
peopleDataJSONP({"user":"Smith"})
Menerima dalam bentuk ini memungkinkan kita untuk menggunakan data dalam peopleDataJSONP
fungsi kita . JSONP adalah praktik yang buruk , jangan menggunakannya (baca di bawah)
Masalah
Katakanlah kita sedang menavigasi ourweb.com
, dan kami ingin mendapatkan data JSON (atau data mentah apa pun) dari anotherweb.com
. Jika kami menggunakan permintaan GET (seperti XMLHttpRequest
, fetch
panggilan $.ajax
, dll.), Browser kami akan memberi tahu kami bahwa itu tidak diizinkan dengan kesalahan jelek ini:
Bagaimana cara mendapatkan data yang kita inginkan? Yah, <script>
tag tidak dikenakan batasan seluruh server (asal *) ini! Itu sebabnya kami dapat memuat pustaka seperti jQuery atau Google Maps dari server apa pun, seperti CDN, tanpa kesalahan.
Poin penting : jika Anda memikirkannya, pustaka tersebut adalah kode JS aktual yang dapat dijalankan (biasanya fungsi besar dengan semua logika di dalamnya). Tapi data mentah? Data JSON bukan kode . Tidak ada yang bisa dijalankan; itu hanya data biasa.
Karenanya, tidak ada cara untuk menangani atau memanipulasi data berharga kami. Browser akan mengunduh data yang ditunjukkan oleh <script>
tag kami dan ketika memprosesnya akan mengeluh:
apa {"user":"Smith"}
omong kosong ini kita muat? Itu bukan kode. Saya tidak dapat menghitung, kesalahan sintaksis!
Retas JSONP
Cara lama / hacky untuk memanfaatkan data itu? Kami membutuhkan server itu untuk mengirimkannya dengan beberapa logika, jadi ketika itu dimuat, kode Anda di browser akan dapat menggunakan data tersebut. Jadi server asing mengirimi kami data JSON di dalam fungsi JS. Data itu sendiri diatur sebagai input fungsi itu. Ini terlihat seperti ini:
peopleDataJSONP({"user":"Smith"})
yang membuatnya menjadi kode JS browser kita akan diurai tanpa mengeluh! Persis seperti halnya dengan pustaka jQuery. Sekarang, untuk mendapatkannya seperti itu, klien "meminta" server JSONP-friendly untuk itu, biasanya dilakukan seperti ini:
<script src="https://anotherweb.com/api/data-from-people.json?myCallback=peopleDataJSONP"></script>
Browser kami akan menerima JSONP dengan nama fungsi itu, maka kami membutuhkan fungsi dengan nama yang sama dalam kode kami, seperti ini:
const peopleDataJSONP = function(data){
alert(data.user); // "Smith"
}
Atau seperti ini, hasil yang sama:
function peopleDataJSONP(data){
alert(data.user); // "Smith"
}
Browser akan mengunduh JSONP dan menjalankannya, yang memanggil fungsi kami , di mana argumennya data
adalah JSON kami. Kita sekarang dapat melakukan dengan data apa pun yang kita inginkan.
Jangan gunakan JSONP, gunakan CORS
JSONP adalah peretasan lintas situs dengan beberapa kelemahan:
- Kami hanya dapat melakukan permintaan GET
- Karena ini adalah permintaan GET yang dipicu oleh tag skrip sederhana, kami tidak mendapatkan kesalahan bermanfaat atau info kemajuan
- Ada juga beberapa masalah keamanan, seperti menjalankan kode JS klien Anda yang dapat diubah menjadi muatan berbahaya
- Ini hanya menyelesaikan masalah dengan data JSON, tetapi kebijakan keamanan Same-Origin berlaku untuk data lain (WebFonts, gambar / video yang diambil dengan drawImage () ...)
- Itu tidak terlalu elegan atau mudah dibaca.
Yang perlu diperhatikan adalah tidak perlu menggunakannya saat ini .
JSONP adalah trik untuk mendapatkan data JSON dari server lain, tetapi kami akan melanggar prinsip keamanan yang sama (Asal-Sama) jika kita memerlukan jenis lain dari hal-hal lintas situs.
Anda harus membaca tentang CORS di sini , tetapi intinya adalah:
Cross-Origin Resource Sharing (CORS) adalah mekanisme yang menggunakan tajuk HTTP tambahan untuk memberi tahu peramban agar memberikan aplikasi web yang berjalan di satu sumber, akses ke sumber daya yang dipilih dari sumber yang berbeda. Aplikasi web mengeksekusi permintaan HTTP lintas-asal ketika ia meminta sumber daya yang memiliki asal yang berbeda (domain, protokol, atau port) dari miliknya.
* asal didefinisikan oleh 3 hal: protokol , port , dan host . Jadi, misalnya, https://web.com
adalah asal yang berbeda dari http://web.com
(protokol berbeda) dan https://web.com:8081
(port berbeda) dan jelas https://thatotherweb.net
(host berbeda)