Teknik "eval ()" dan "JSON.parse ()" menggunakan format yang saling eksklusif.
- Dengan "eval ()" kurung yang diperlukan .
- Dengan tanda kurung "JSON.parse ()" dilarang .
Hati-hati, ada fungsi "stringify ()" yang menghasilkan format "eval". Untuk ajax, Anda harus menggunakan hanya format JSON.
Meskipun "eval" menggabungkan seluruh bahasa JavaScript, JSON hanya menggunakan sebagian kecil dari bahasa tersebut. Di antara konstruksi dalam bahasa JavaScript yang harus dikenali "eval" adalah "Pernyataan blok" (alias "pernyataan gabungan") ; yang merupakan sepasang atau tanda kurung kurawal "{}" dengan beberapa pernyataan di dalamnya. Tapi kurung kurawal juga digunakan dalam sintaks literal objek. Interpretasi dibedakan oleh konteks di mana kode tersebut muncul. Sesuatu mungkin terlihat seperti objek literal bagi Anda, tetapi "eval" akan melihatnya sebagai pernyataan gabungan.
Dalam bahasa JavaScript, literal objek muncul di sebelah kanan tugas.
var myObj = { ...some..code..here... };
Literal objek tidak muncul dengan sendirinya.
{ ...some..code..here... }
Kembali ke pertanyaan awal OP, yang ditanyakan pada tahun 2008, dia bertanya mengapa hal berikut gagal dalam "eval ()":
{ title: "One", key: "1" }
Jawabannya adalah ini terlihat seperti pernyataan majemuk. Untuk mengubahnya menjadi objek, Anda harus meletakkannya ke dalam konteks di mana pernyataan majemuk tidak mungkin. Itu dilakukan dengan meletakkan tanda kurung di sekitarnya
( { title: "One", key: "1" } )
OP juga bertanya mengapa pernyataan serupa lakukan berhasil eval:
[ { title: "One", key: "1" }, { title: "Two", key: "2" } ]
Jawaban yang sama berlaku - kurung kurawal berada dalam konteks di mana pernyataan majemuk tidak mungkin. Ini adalah konteks larik, " [...]
", dan larik bisa berisi objek, tapi tidak bisa berisi pernyataan.
Tidak seperti "eval ()", JSON sangat terbatas kemampuannya. Batasannya disengaja. Perancang JSON menginginkan subset JavaScript yang minimalis, hanya menggunakan sintaks yang dapat muncul di sisi kanan tugas. Jadi jika Anda memiliki beberapa kode yang diurai dengan benar di JSON ...
var myVar = JSON.parse("...some...code...here...");
... yang menyiratkan itu juga akan mengurai secara hukum di sisi kanan tugas, seperti ini ..
var myVar = ...some..code..here... ;
Tapi itu bukan satu-satunya batasan pada JSON. The BNF spesifikasi bahasa untuk JSON sangat sederhana. Misalnya, ini tidak mengizinkan penggunaan tanda kutip tunggal untuk menunjukkan string (seperti JavaScript dan Perl) dan tidak memiliki cara untuk mengekspresikan karakter tunggal sebagai byte (seperti 'C'). Sayangnya, ini juga tidak mengizinkan komentar (yang akan sangat bagus saat membuat file konfigurasi). Keuntungan dari semua batasan tersebut adalah penguraian JSON cepat dan tidak menawarkan kesempatan untuk injeksi kode (ancaman keamanan).
Karena keterbatasan ini, JSON tidak menggunakan tanda kurung. Akibatnya, tanda kurung dalam string JSON merupakan karakter ilegal.
Selalu gunakan format JSON dengan ajax, karena alasan berikut:
- Pipeline ajax tipikal akan dikonfigurasi untuk JSON.
- Penggunaan "eval ()" akan dikritik sebagai risiko keamanan.
Sebagai contoh pipeline ajax, pertimbangkan program yang melibatkan server Node dan klien jQuery. Program klien menggunakan panggilan jQuery yang memiliki formulir $.ajax({dataType:'json',...etc.});
. JQuery membuat objek jqXHR untuk digunakan nanti, lalu memaketkan dan mengirim permintaan terkait. Server menerima permintaan tersebut, memprosesnya, dan kemudian siap untuk merespons. Program server akan memanggil metode res.json(data)
untuk mengemas dan mengirim respons. Kembali ke sisi klien, jQuery menerima respons, berkonsultasi dengan objek jqXHR terkait, dan memproses data yang diformat JSON. Ini semua bekerja tanpa perlu konversi data manual. Responsnya tidak melibatkan panggilan eksplisit ke JSON.stringify () di server Node, dan tidak ada panggilan eksplisit ke JSON.parse () di klien; itu semua ditangani untuk Anda.
Penggunaan "eval" dikaitkan dengan risiko keamanan injeksi kode. Anda mungkin berpikir itu tidak mungkin terjadi, tetapi peretas bisa menjadi sangat kreatif. Selain itu, "eval" bermasalah untuk pengoptimalan Javascript.
Jika Anda menemukan diri Anda menggunakan fungsi "stringify ()", ketahuilah bahwa beberapa fungsi dengan nama itu akan membuat string yang kompatibel dengan "eval" dan tidak dengan JSON. Misalnya, di Node, berikut ini memberi Anda fungsi yang membuat string dalam format yang kompatibel dengan "eval":
var stringify = require('node-stringify');
Ini bisa berguna, tetapi kecuali Anda memiliki kebutuhan khusus, mungkin itu bukan yang Anda inginkan.