Deserializar un JSON en un objeto JavaScript

266

Tengo una cadena en una aplicación de servidor Java a la que se accede mediante AJAX. Se parece a lo siguiente:

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

Cuando la cadena se extrae del servidor, ¿hay una manera fácil de convertir esto en un objeto (o matriz) de JavaScript vivo? ¿O tengo que dividir manualmente la cadena y construir mi objeto manualmente?

mj_
fuente
posible duplicado de cómo analizar json en javascript
Felix Kling
¿Posible duplicado de Parse JSON en JavaScript?
m93a

Respuestas:

397

Soporte de navegadores modernos JSON.parse().

var arr_from_json = JSON.parse( json_string );

En los navegadores que no lo hacen, puede incluir la json2biblioteca .

usuario113716
fuente
¿Cómo funcionará para los campos de fecha en JSON, por ejemplo, {StartDate: "\ / Date (1372575600000) \ /"}?
Philipp Munin
@PhilippMunin, puede usar esta función Fecha desde la API de JavaScript: nueva Fecha (parseInt ("/ Date (946681200000) /". Replace ('/ Date (', '')));
Leo
u objetos Map (), etc., ¿cómo se realiza la deserialización adecuada
Ewan
25

El objetivo de JSON es que las cadenas JSON se pueden convertir en objetos nativos sin hacer nada. Mira este enlace

Puedes usar cualquiera eval(string)o JSON.parse(string).

Sin embargo, evales arriesgado. De json.org:

La función eval es muy rápida. Sin embargo, puede compilar y ejecutar cualquier programa de JavaScript, por lo que puede haber problemas de seguridad. El uso de eval se indica cuando la fuente es confiable y competente. Es mucho más seguro usar un analizador JSON. En las aplicaciones web sobre XMLHttpRequest, la comunicación solo se permite al mismo origen que proporciona esa página, por lo que es de confianza. Pero puede que no sea competente. Si el servidor no es riguroso en su codificación JSON, o si no valida escrupulosamente todas sus entradas, entonces podría entregar texto JSON inválido que podría llevar un script peligroso. La función eval ejecutaría el script, desatando su malicia.

Abhinav
fuente
1
No entiendo el riesgo. ¿Nadie puede usar un depurador js para inyectar y ejecutar cualquier script que quieran de todos modos?
xr280xr
3
@ xr280xr Sí, pero eso ocurre solo localmente en su navegador, no todos los navegadores que descargan el sitio web.
masterxilo
16

¡Haz lo que hace jQuery! (la esencia)

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

De esta manera, no necesita ninguna biblioteca externa y todavía funciona en navegadores antiguos.

Ravan Scafi
fuente
77
Parece que está volviendo al equivalente de eval().
LarsH
1
Esto es peligroso, eval es malo!
caesarsol
8

PARA recopilar todos los elementos de una matriz y devolver un objeto 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;
    },

PARA analizar los mismos datos que pasamos de esta manera

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

}
Tarun Gupta
fuente
4

También podría usar, eval()pero JSON.parse()es una forma más segura y fácil, entonces ¿por qué lo haría?

bueno y funciona

var yourJsonObject = JSON.parse(json_as_text);

No veo ninguna razón por la que preferiría usar eval. Solo pone su aplicación en riesgo.

Dicho esto, esto también es posible.

malo, pero también funciona

var yourJsonObject = eval(json_as_text);

¿Por qué es evaluna mala idea?

Considere el siguiente ejemplo.

Algunos terceros o usuarios proporcionaron datos de cadena 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"
}]
`;

Su script del lado del servidor procesa esos datos.

Utilizando JSON.parse:

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

arrojará:

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

La función no se ejecutará.

Estás seguro.

Utilizando eval():

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

ejecutará la función y devolverá el texto.

Si reemplazo esa función inofensiva con una que elimina archivos de la carpeta de su sitio web, ha sido pirateado. No se arrojarán errores / advertencias en este ejemplo.

NO estás a salvo.

Pude manipular una cadena de texto JSON para que actúe como una función que se ejecutará en el servidor.

eval(JSON)[0].adjacencies[0].nodeTo espera procesar una cadena JSON pero, en realidad, acabamos de ejecutar una función en nuestro servidor.

Esto también podría evitarse si verificamos en el servidor todos los datos proporcionados por el usuario antes de pasarlos a una eval()función, pero ¿por qué no usar la herramienta integrada para analizar JSON y evitar todos estos problemas y peligros?

DevWL
fuente
1

Y si también desea que el objeto deserializado tenga funciones, puede usar mi pequeña herramienta: 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());
fishgen
fuente
0

Si pega la cadena en el lado del servidor en el html, no necesita hacer nada:

Para Java simple en jsp:

var jsonObj=<%=jsonStringInJavaServlet%>;

Para puntales de ancho jsp:

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