jQuery no analizará mi JSON de la consulta AJAX

Tengo problemas para analizar algunos datos JSON devueltos por mi servidor usando jQuery.ajax ()

Para realizar el AJAX que estoy usando:

$.ajax({ url: myUrl, cache: false, dataType: "json", success: function(data){ ... }, error: function(e, xhr){ ... } }); 

Y si devuelvo una serie de elementos, entonces funciona bien:

 [ { title: "One", key: "1" }, { title: "Two", key: "2" } ] 

La función de éxito se llama y recibe el objeto correcto.

Sin embargo, cuando bash devolver un solo objeto:

 { title: "One", key: "1" } 

La función de error se llama y xhr contiene ‘parsererror’. Intenté incluir el JSON entre paréntesis en el servidor antes de enviarlo por el cable, pero no importa. Sin embargo, si pego el contenido en una cadena en Javascript y luego uso la función eval (), la evalúa perfectamente.

¿Alguna idea de lo que estoy haciendo mal?

Antonio

¿Su servidor está enviando datos como Content-Type "*/json" ? De lo contrario, modifique los encabezados de respuesta en consecuencia. Enviar "application/json" estaría bien, por ejemplo.

De acuerdo con la especificación json.org , su devolución no es válida. Los nombres siempre se citan, por lo que debe regresar

 { "title": "One", "key": "1" } 

y

 [ { "title": "One", "key": "1" }, { "title": "Two", "key": "2" } ] 

Puede que este no sea el problema con su configuración, ya que dice que uno de ellos funciona ahora, pero debería corregirse en caso de que necesite cambiar a otro analizador JSON en el futuro.

Las cadenas JSON están envueltas en comillas dobles ; las comillas simples no son un sustituto válido.

 {"who": "Hello World"} 

es válido pero esto no es …

 {'who': 'Hello World'} 

Si bien no es el problema de OP, pensé que vale la pena señalar para otros que aterrizan aquí.

Este problema generalmente se debe a que su solicitud recibió el tipo de mime equivocado. Al desarrollar en su propia computadora, a veces no está recibiendo el tipo de mime apropiado del “servidor”, que es su propia computadora. Me encontré con este problema una vez cuando desarrollé abriendo el archivo almacenado localmente en el navegador (por ejemplo, la url era “c: /project/test.html”).

Intente utilizar la propiedad beforeSend para agregar una función de callback que anule el tipo de mimo. Esto engañará al código para que se ocupe de json a pesar de que el servidor envía el tipo de mime equivocado y el código de llamada lo recibe. Algunos ejemplos de código están debajo.

El tipo de mime apropiado es application / json según esta pregunta , pero sé que la aplicación / j-son funcionó cuando lo probé (hace varios años). Probablemente deberías probar application / json primero.

 var jsonMimeType = "application/json;charset=UTF-8"; $.ajax({ type: "GET", url: myURL, beforeSend: function(x) { if(x && x.overrideMimeType) { x.overrideMimeType(jsonMimeType); } }, dataType: "json", success: function(data){ // do stuff... } }); 

Tuve este problema y durante un tiempo utilicé

 eval('('+data+')') 

para obtener los datos devueltos en un objeto. pero luego tuvo otros problemas al obtener el error “falta entre paréntesis” y descubrió que jQuery tiene una función específica para evaluar una cadena para una estructura json:

 $.parseJSON(data) 

debería hacer el truco. Esto es además de tener tu cadena json en el formato apropiado, por supuesto …

Si hace eco de la respuesta json y sus encabezados no coinciden con * / json, puede usar la API integrada jQuery.parseJSON para analizar la respuesta.

 response = '{"name":"John"}'; var obj = jQuery.parseJSON(response); alert( obj.name === "John" ); 
 { title: "One", key: "1" } 

No es lo que piensas Como expresión, es un Object literal, pero como una statement, es:

 { // new block title: // define a label called 'title' for goto statements "One", // statement: the start of an expression which will be ignored key: // ...er, what? you can't have a goto label in the middle of an expression // ERROR 

Lamentablemente, eval () no le da una forma de especificar si le está dando una statement o una expresión, y tiende a adivinar mal.

La solución habitual es, de hecho, ajustar todo entre paréntesis antes de enviarlo a la función eval (). Dice que lo ha intentado en el servidor … claramente, de alguna manera, eso no está llegando. Debería ser resistente al agua para decir al final del cliente, lo que sea que esté recibiendo la respuesta XMLHttpRequest:

 eval('('+responseText+')'); 

en lugar de:

 eval(responseText); 

siempre que la respuesta sea realmente una expresión, no una statement. (por ejemplo, no tiene cláusulas múltiples separadas por punto y coma o línea nueva).

Si consume ASP.NET Web Services utilizando jQuery, asegúrese de tener lo siguiente incluido en su web.config:

       

Tuve un problema similar al de Firefox 3.5 que funcionaba bien y analizaba mis datos JSON pero Firefox 3.0.6 devolvía un error parcial. Resultó que era un espacio en blanco al inicio del JSON que causó que Firefox 3.0.6 arrojara un error. Eliminar el espacio en blanco lo arregló

Tendrás que establecer el tipo de contenido del encabezado en tu php de esta manera:

   

Mire estos videos para una mejor comprensión …

Referencia: http://www.youtube.com/watch?v=EvFXWqEqh6o

Las técnicas “eval ()” y “JSON.parse ()” usan formatos mutuamente excluyentes.

  • Con el paréntesis “eval ()” son obligatorios .
  • Con el paréntesis “JSON.parse ()” están prohibidos .

Tenga cuidado, hay funciones “stringify ()” que producen el formato “eval”. Para ajax, debe usar solo el formato JSON.

Mientras que “eval” incorpora todo el lenguaje JavaScript, JSON usa solo un pequeño subconjunto del lenguaje. Entre los constructos en el lenguaje JavaScript que “eval” debe reconocer está la “instrucción de bloque” (también conocida como “statement compuesta”) ; que es un par o llaves “{}” con algunas frases adentro. Pero las llaves también se utilizan en la syntax de los literales de objetos. La interpretación se diferencia por el contexto en el que aparece el código. Algo podría parecerle un objeto literal, pero “eval” lo verá como una statement compuesta.

En el lenguaje JavaScript, los literales de objetos se encuentran a la derecha de una tarea.

 var myObj = { ...some..code..here... }; 

Los literales de objeto no ocurren por sí solos.

 { ...some..code..here... } // this looks like a compound statement 

Volviendo a la pregunta original del OP, realizada en 2008, preguntó por qué falla lo siguiente en “eval ()”:

 { title: "One", key: "1" } 

La respuesta es que parece una statement compuesta. Para convertirlo en un objeto, debe ponerlo en un contexto donde una statement compuesta es imposible. Eso se hace poniendo paréntesis alrededor

 ( { title: "One", key: "1" } ) // not a compound statment, so must be object literal 

El PO también preguntó por qué una statement similar había evaluado con éxito:

 [ { title: "One", key: "1" }, { title: "Two", key: "2" } ] 

Se aplica la misma respuesta: las llaves se encuentran en un contexto donde una statement compuesta es imposible. Este es un contexto de matriz, ” [...] “, y las matrices pueden contener objetos, pero no pueden contener declaraciones.

A diferencia de “eval ()”, JSON tiene capacidades muy limitadas. La limitación es intencional. El diseñador de JSON pretendía un subconjunto minimalista de JavaScript, utilizando solo la syntax que podría aparecer en el lado derecho de una tarea. Entonces, si tiene algún código que analice correctamente en JSON …

 var myVar = JSON.parse("...some...code...here..."); 

… eso implica que también analizará legalmente en el lado derecho de una tarea, como este ..

 var myVar = ...some..code..here... ; 

Pero esa no es la única restricción en JSON. La especificación del lenguaje BNF para JSON es muy simple. Por ejemplo, no permite el uso de comillas simples para indicar cadenas (como JavaScript y Perl do) y no tiene una forma de express un solo carácter como un byte (como ‘C’). Desafortunadamente, tampoco permite comentarios (lo que sería realmente bueno al crear archivos de configuración). La ventaja de todas esas limitaciones es que el análisis de JSON es rápido y no ofrece ninguna oportunidad para la inyección de código (una amenaza para la seguridad).

Debido a estas limitaciones, JSON no tiene uso para paréntesis. En consecuencia, un paréntesis en una cadena JSON es un carácter ilegal.

Utilice siempre el formato JSON con ajax, por las siguientes razones:

  • Una tubería Ajax típica se configurará para JSON.
  • El uso de “eval ()” será criticado como un riesgo de seguridad.

Como ejemplo de una canalización de Ajax, considere un progtwig que involucre un servidor Node y un cliente jQuery. El progtwig cliente usa una llamada jQuery que tiene el formato $.ajax({dataType:'json',...etc.}); . JQuery crea un objeto jqXHR para su uso posterior, luego empaqueta y envía la solicitud asociada. El servidor acepta la solicitud, la procesa y luego está listo para responder. El progtwig del servidor llamará al método res.json(data) para empaquetar y enviar la respuesta. De vuelta en el lado del cliente, jQuery acepta la respuesta, consulta el objeto jqXHR asociado y procesa los datos formateados JSON. Todo esto funciona sin necesidad de conversión manual de datos. La respuesta no implica una llamada explícita a JSON.stringify () en el servidor de nodo y ninguna llamada explícita a JSON.parse () en el cliente; eso es todo manejado para ti.

El uso de “eval” está asociado con riesgos de seguridad de inyección de código. Puede pensar que no hay forma de que eso suceda, pero los hackers pueden ser bastante creativos. Además, “eval” es problemático para la optimización de Javascript.

Si se encuentra usando una función “stringify ()”, tenga en cuenta que algunas funciones con ese nombre crearán cadenas que son compatibles con “eval” y no con JSON. Por ejemplo, en Node, lo siguiente le da una función que crea cadenas en formato compatible con “eval”:

 var stringify = require('node-stringify'); // generates eval() format 

Esto puede ser útil, pero a menos que tenga una necesidad específica, probablemente no sea la que usted desea.

Si devolver una matriz funciona y devolver un solo objeto no lo hace, también puede intentar devolver su único objeto como una matriz que contiene ese único objeto:

 [ { title: "One", key: "1" } ] 

de esa forma, devuelve una estructura de datos coherente, una matriz de objetos, sin importar la carga de datos.

veo que has intentado envolver tu único objeto en “paréntesis”, y sugerir esto con un ejemplo porque, por supuesto, JavaScript trata [..] de manera diferente que (…)

Si se llama al manejador de errores de jQuery y el objeto XHR contiene “error del analizador”, es probable que sea un error del analizador que vuelve del servidor.

¿Es su escenario de resultado múltiple cuando llama al servicio sin un parámetro, pero se está interrumpiendo cuando intenta suministrar un parámetro para recuperar el registro individual?

¿De qué backend estás devolviendo esto?

En los servicios ASMX, por ejemplo, ese suele ser el caso cuando los parámetros se suministran a jQuery como un objeto JSON en lugar de una cadena JSON. Si le proporciona a jQuery un objeto JSON real para su parámetro “datos”, lo serializará en pares k y v estándar y delimitados en lugar de enviarlo como JSON.

Encontré en algunas de mis implementaciones que tuve que agregar:

 obj = new Object; obj = (data.obj); 

que parecía resolver el problema. Evaluar o no, pareció hacer exactamente lo mismo para mí.

jQuery se ahoga en ciertas teclas JSON. Estaba enviando este fragmento de JSON en PHP:

 echo json_encode((object) array('result' => 'success')); 

Cambiar el nombre de la tecla ‘resultado’ a otra cosa funciona. Supongo que se trata de una colisión de palabras reservadas de algún tipo, y podría ser un error en jQuery (1.4.2).

En un entorno de ColdFusion, una cosa que causará un error, incluso con JSON bien formado, es activar Enable Request Debugging Output en ColdFusion Administrator (en Debugging & Logging> Debug Output Settings). La información de depuración se devolverá con los datos JSON y, por lo tanto, la invalidará.

también intente esto

 $.ajax({ url: url, data:datas, success:function(datas, textStatus, jqXHR){ var returnedData = jQuery.parseJSON(datas.substr(datas.indexOf('{'))); })}; 

en mi caso, el servidor responde con un carácter desconocido antes de ‘{‘

Obtenía status = parseerror y xhr.status = 200.

El problema para mí fue que la URL dentro de la respuesta JSON tenía ‘\’ cambiando a ‘/’ solucionado esto.

Estaba luchando con esto y pasé unas horas tratando de resolver esto, hasta que usé Firebug para mostrar el objeto de datos.

 var data = eval("(" + data.responseText + ")"); console.log(data.count); 

utilizar

 $data = yourarray(); json_encode($data) 

en el lado del servidor. En el lado del cliente, use ajax con Datatype JSON y asegúrese de que la encoding de su documento no sea UTF-8 con BOM, tiene que ser UTF-8.