Las técnicas " eval() "y" JSON.parse() "usan formatos mutuamente excluyentes.
- Con "eval()" paréntesis se requiere .
- Con el paréntesis "JSON.parse()" son prohibido.
Tenga en cuenta que existen 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 idioma. Entre los constructos en el lenguaje JavaScript que "eval" debe reconocer está el "Block statement" (a.k.a. "compound statement"); que es un par o llaves "{}" con algunas frases adentro. Pero las llaves también se utilizan en la sintaxis 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 declaración compuesta.
En el lenguaje de JavaScript, los literales de objeto se encuentran a la derecha de una tarea.
var myObj = { ...some..code..here... };
Los literales de objetos no aparecen por sí solos.
{ ...some..code..here... } // this looks like a compound statement
Volviendo a la pregunta original del OP, se le preguntó en 2008, él les preguntó por qué la siguiente falla en "eval()":
{ title: "One", key: "1" }
La respuesta es que se ve como una sentencia compuesta. Para convertirlo en un objeto, debe ponerlo en un contexto donde una declaración compuesta es imposible. Esto se hace poniendo entre paréntesis alrededor
({ title: "One", key: "1" }) // not a compound statment, so must be object literal
El PO también preguntó por qué una declaración similar hizo éxito eval:
[ { title: "One", key: "1" }, { title: "Two", key: "2" } ]
Se aplica la misma respuesta - las llaves están en un contexto en el una declaración compuesta es imposible. Este es un contexto de matriz, "[...]
", y las matrices pueden contener objetos, pero no pueden contener sentencias.
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 sintaxis que podría aparecer en el lado derecho de una tarea. Así que si usted tiene algún código que analiza correctamente en JSON ...
var myVar = JSON.parse("...some...code...here...");
... que implica también analizará legalmente en el lado derecho de una asignación, como este ..
var myVar = ...some..code..here... ;
Pero esa no es la única restricción en JSON. El BNF language specification for 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 expresar 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.
Siempre use formato JSON con el Ajax, por las siguientes razones:
- Una tubería típica ajax se configurará para JSON.
- El uso de "eval()" será criticado como un riesgo de seguridad.
Como un ejemplo de una tubería ajax, considere un programa que involucre un servidor Node y un cliente jQuery. El programa cliente utiliza 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 programa 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 los riesgos de seguridad de la 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 el nodo, el siguiente le da función que crea cadenas en formato compatible "eval":
var stringify = require('node-stringify'); // generates eval() format
Esto puede ser útil, pero a menos que tenga una necesidad específica, probablemente no es lo que quiere.
Relacionado: http://stackoverflow.com/questions/631418/jquery-getjson-ajax-parseerror –