Deserializing JSON menjadi objek JavaScript


266

Saya memiliki string dalam aplikasi server Java yang diakses menggunakan AJAX. Itu terlihat seperti berikut ini:

var json = [{
    "adjacencies": [
        {
          "nodeTo": "graphnode2",
          "nodeFrom": "graphnode1",
          "data": {
            "$color": "#557EAA"
          }
        }
    ],
    "data": {
      "$color": "#EBB056",
      "$type": "triangle",
      "$dim": 9
    },
    "id": "graphnode1",
    "name": "graphnode1"
},{
    "adjacencies": [],
    "data": {
      "$color": "#EBB056",
      "$type": "triangle",
      "$dim": 9
    },
    "id": "graphnode2",
    "name": "graphnode2"
}];

Ketika string ditarik dari server, apakah ada cara mudah untuk mengubahnya menjadi objek JavaScript (atau array) yang hidup? Atau apakah saya harus membagi string secara manual dan membangun objek secara manual?



Kemungkinan duplikat Parse JSON dalam JavaScript?
m93a

Jawaban:


397

Dukungan browser modern JSON.parse().

var arr_from_json = JSON.parse( json_string );

Dalam browser yang tidak, Anda dapat menyertakan satu json2perpustakaan .


Bagaimana itu akan bekerja untuk bidang tanggal di JSON, misalnya {StartDate: "\ / Date (1372575600000) \ /"}?
Philipp Munin

@PhilippMunin Anda dapat menggunakan fungsi Tanggal ini dari API javascript: Date baru (parseInt ("/ Date (946681200000) /". Replace ('/ Date (', '')));
Leo

atau Map () objek dll, bagaimana Anda melakukan deserialisation yang tepat
Ewan

25

Inti dari JSON adalah bahwa string JSON dapat dikonversi ke objek asli tanpa melakukan apa pun. Periksa tautan ini

Anda dapat menggunakan salah satu eval(string)atau JSON.parse(string).

Namun, evalberisiko. Dari json.org:

Fungsi eval sangat cepat. Namun, itu dapat mengkompilasi dan menjalankan program JavaScript apa pun, sehingga bisa ada masalah keamanan. Penggunaan eval ditunjukkan ketika sumbernya dipercaya dan kompeten. Jauh lebih aman untuk menggunakan parser JSON. Dalam aplikasi web melalui XMLHttpRequest, komunikasi hanya diizinkan untuk asal yang sama yang menyediakan halaman itu, sehingga dipercaya. Tapi itu mungkin tidak kompeten. Jika server tidak teliti dalam pengkodean JSON-nya, atau jika tidak dengan teliti memvalidasi semua inputnya, maka itu bisa mengirimkan teks JSON tidak valid yang bisa membawa skrip berbahaya. Fungsi eval akan menjalankan script, melepaskan kebenciannya.


1
Saya tidak mengerti risikonya. Tidak bisakah ada yang menggunakan debugger js untuk menyuntikkan dan menjalankan skrip apa pun yang mereka inginkan?
xr280xr

3
@ xr280xr Ya, tapi itu hanya terjadi secara lokal di browser mereka, tidak setiap browser yang mengunduh situs web.
masterxilo

16

Lakukan seperti jQuery! (esensi)

function parseJSON(data) {
    return window.JSON && window.JSON.parse ? window.JSON.parse( data ) : (new Function("return " + data))(); 
}
// testing
obj = parseJSON('{"name":"John"}');
alert(obj.name);

Dengan cara ini Anda tidak memerlukan pustaka eksternal dan masih berfungsi di browser lama.


7
Ini sepertinya jatuh kembali ke yang setara dengan eval().
LarsH

1
Ini berbahaya, eval itu jahat!
caesarsol

8

UNTUK mengumpulkan semua item array dan mengembalikan objek json

collectData: function (arrayElements) {

        var main = [];

        for (var i = 0; i < arrayElements.length; i++) {
            var data = {};
            this.e = arrayElements[i];            
            data.text = arrayElements[i].text;
            data.val = arrayElements[i].value;
            main[i] = data;
        }
        return main;
    },

UNTUK mem-parse data yang sama yang kita lalui seperti ini

dummyParse: function (json) {       
        var o = JSON.parse(json); //conerted the string into JSON object        
        $.each(o, function () {
            inner = this;
            $.each(inner, function (index) {
                alert(this.text)
            });
        });

}

4

Anda juga bisa menggunakan eval()tetapi JSON.parse()lebih aman dan lebih mudah, jadi mengapa Anda mau?

bagus dan bekerja

var yourJsonObject = JSON.parse(json_as_text);

Saya tidak melihat alasan mengapa Anda lebih suka menggunakannya eval. Itu hanya menempatkan aplikasi Anda dalam risiko.

Yang mengatakan - ini adalah juga mungkin.

buruk - tetapi juga berfungsi

var yourJsonObject = eval(json_as_text);

Mengapa itu evalide yang buruk?

Perhatikan contoh berikut.

Beberapa pihak ketiga atau pengguna menyediakan data string JSON.

var json = `
[{
    "adjacencies": [
        {
          "nodeTo": function(){
            return "delete server files - you have been hacked!";
          }(),
          "nodeFrom": "graphnode1",
          "data": {
            "$color": "#557EAA"
          }
        }
    ],
    "data": {
      "$color": "#EBB056",
      "$type": "triangle",
      "$dim": 9
    },
    "id": "graphnode1",
    "name": "graphnode1"
},{
    "adjacencies": [],
    "data": {
      "$color": "#EBB056",
      "$type": "triangle",
      "$dim": 9
    },
    "id": "graphnode2",
    "name": "graphnode2"
}]
`;

Skrip sisi server Anda memproses data itu.

Menggunakan JSON.parse:

window.onload = function(){
  var placeholder = document.getElementById('placeholder1');
  placeholder.innerHTML = JSON.parse(json)[0].adjacencies[0].nodeTo;
}

akan melempar:

Uncaught SyntaxError: Unexpected token u in JSON at position X. 

Fungsi tidak akan dieksekusi.

Kamu aman.

Menggunakan eval():

window.onload = function(){
  var placeholder = document.getElementById('placeholder1');
  placeholder.innerHTML = eval(json)[0].adjacencies[0].nodeTo;
}

akan menjalankan fungsi dan mengembalikan teks.

Jika saya mengganti fungsi yang tidak berbahaya itu dengan yang menghapus file dari folder situs web Anda, Anda telah diretas. Tidak ada kesalahan / peringatan akan dilemparkan dalam contoh ini.

Anda TIDAK aman.

Saya bisa memanipulasi string teks JSON sehingga berfungsi sebagai fungsi yang akan dijalankan di server.

eval(JSON)[0].adjacencies[0].nodeTo mengharapkan untuk memproses string JSON tetapi, pada kenyataannya, kami baru saja menjalankan suatu fungsi pada server kami.

Ini juga bisa dicegah jika kita sisi server memeriksa semua data yang disediakan pengguna sebelum meneruskannya ke eval()fungsi tetapi mengapa tidak hanya menggunakan alat bawaan untuk mem-parsing JSON dan menghindari semua masalah dan bahaya ini?


1

Dan jika Anda juga ingin objek deserialised memiliki fungsi, Anda dapat menggunakan alat kecil saya: https://github.com/khayll/jsmix

//first you'll need to define your model
var GraphNode = function() {};
GraphNode.prototype.getType = function() {
   return this.$type;
}

var Adjacency = function() {};
Adjacency.prototype.getData =n function() {
    return this.data;
}

//then you could say:
var result = JSMix(jsonData)
    .withObject(GraphNode.prototype, "*")
    .withObject(Adjacency.prototype, "*.adjacencies")
    .build();

//and use them
console.log(result[1][0].getData());

0

Jika Anda menempelkan string di sisi server ke html tidak perlu melakukan apa pun:

Untuk java biasa di jsp:

var jsonObj=<%=jsonStringInJavaServlet%>;

Untuk strut lebar jsp:

var jsonObj=<s:property value="jsonStringInJavaServlet" escape="false" escapeHtml="false"/>;

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.