Bir JSON'un JavaScript nesnesine serisini kaldırma


266

AJAX kullanılarak erişilen bir Java sunucu uygulamasında bir dize var. Aşağıdaki gibi bir şey görünüyor:

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"
}];

Dize sunucudan alındığında, bunu yaşayan bir JavaScript nesnesine (veya dizisine) dönüştürmenin kolay bir yolu var mı? Yoksa dizeyi el ile bölmek ve nesneyi el ile oluşturmak zorunda mıyım?



Yanıtlar:


397

Modern tarayıcı desteği JSON.parse().

var arr_from_json = JSON.parse( json_string );

Yok tarayıcılarda, içerebilir kütüphane .json2


JSON'daki tarih alanları için bu nasıl çalışır, örneğin {StartDate: "\ / Date (1372575600000) \ /"}?
Philipp Munin

@PhilippMunin javascript API'sinden bu Date işlevini kullanabilirsiniz: new Date (parseInt ("/ Date (946681200000) /". Replace ('/ Date (', '')));
Leo

veya Harita () vb nesneleri nasıl yaparsınız uygun deserialisation
Ewan

25

JSON'un bütün mesele JSON dizelerinin hiçbir şey yapmadan yerel nesnelere dönüştürülebilmesidir. Bu bağlantıyı kontrol et

Ya kullanabilir eval(string)veya JSON.parse(string).

Ancak evalrisklidir. Json.org adresinden:

Eval fonksiyonu çok hızlı. Ancak, herhangi bir JavaScript programını derleyebilir ve yürütebilir, böylece güvenlik sorunları olabilir. Eval kullanımı kaynak güvenilir ve yetkin olduğunda belirtilir. JSON ayrıştırıcı kullanmak çok daha güvenlidir. XMLHttpRequest üzerinden web uygulamalarında iletişime yalnızca o sayfayı sağlayan aynı kaynaktan izin verilir, bu nedenle güvenilirdir. Ancak yetkin olmayabilir. Sunucu, JSON kodlamasında titiz değilse veya tüm girişlerini titizlikle doğrulamazsa, tehlikeli komut dosyası taşıyabilecek geçersiz JSON metni verebilir. Eval fonksiyonu betiği kötülüğünü açığa çıkararak yürütür.


1
Riski anlamıyorum. Herkes zaten istediği komut dosyası enjekte ve yürütmek için bir js hata ayıklayıcı kullanamazsınız?
xr280xr

3
@ xr280xr Evet, ancak web sitesini indiren her tarayıcıda değil, yalnızca tarayıcılarında yerel olarak gerçekleşir.
masterxilo

16

JQuery gibi yapın! (öz)

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);

Bu şekilde harici bir kütüphaneye ihtiyacınız yoktur ve hala eski tarayıcılarda çalışır.


7
Bu, eşdeğerine geri düşüyor gibi görünüyor eval().
LarsH

1
Bu tehlikelidir, eval kötüdür!
caesarsol

8

Bir dizinin tüm öğelerini toplamak ve bir json nesnesi döndürmek için

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;
    },

Aynı verileri bu şekilde incelemek

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

Ayrıca kullanabilirsiniz, eval()ancak JSON.parse()daha güvenli ve daha kolay bir yol, neden?

iyi ve çalışıyor

var yourJsonObject = JSON.parse(json_as_text);

Kullanmayı tercih etmek için hiçbir neden göremiyorum eval. Sadece uygulamanızı riske atar.

Yani - bu olduğunu da mümkündür.

kötü - ama aynı zamanda çalışıyor

var yourJsonObject = eval(json_as_text);

Neden evalkötü bir fikir?

Aşağıdaki örneği ele alalım.

Bazı üçüncü taraflar veya kullanıcılar JSON dize verileri sağladı.

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"
}]
`;

Sunucu tarafı komut dosyanız bu verileri işler.

Kullanma JSON.parse:

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

atacak:

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

İşlev yürütülmez.

Sen güvendesin.

Kullanma eval():

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

işlevi yürütür ve metni döndürür.

Bu zararsız işlevi, web sitesi klasörünüzdeki dosyaları kaldıran bir işlevle değiştirirsem saldırıya uğradınız. Bu örnekte hiçbir hata / uyarı verilmeyecektir.

Sen güvende DEĞİLSİN.

Sunucuda yürütecek bir işlev gibi davranır bir JSON metin dizesi manipüle başardı.

eval(JSON)[0].adjacencies[0].nodeTo JSON dizesini işlemeyi umuyor ancak gerçekte sunucumuzda bir fonksiyon yürüttük.

Bu, sunucu tarafında bir eval()işleve geçmeden önce kullanıcı tarafından sağlanan tüm verileri kontrol edersek de önlenebilir, ancak neden JSON'u ayrıştırmak ve tüm bu sorun ve tehlikelerden kaçınmak için yerleşik aracı kullanmıyorsunuz?


1

Ayrıca, serileştirilmiş nesnenin işlevlere sahip olmasını istiyorsanız, küçük aracımı kullanabilirsiniz: 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

Dizeyi html'ye sunucu tarafına yapıştırırsanız hiçbir şey yapmanıza gerek yoktur:

Jsp içinde düz java için:

var jsonObj=<%=jsonStringInJavaServlet%>;

Jsp genişlik destekleri için:

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.