Cómo analizar JSON usando Node.js?


Cómo debo analizar JSON usando Node.js? ¿Hay algún módulo que valide y analice JSON de forma segura?

Author: Krumia, 2011-04-20

29 answers

Simplemente puede usar JSON.parse.

La definición del objeto JSON es parte de la especificación ECMAScript 5. nodo.js se basa en el motor V8 de Google Chrome, que se adhiere al estándar ECMA. Por lo tanto, nodo.js también tiene un objeto global JSON[docs].

Nota - JSON.parse puede atar el hilo porque es un método sincrónico. Entonces, si está planeando analizar objetos JSON grandes, use un streaming json parser.

 1009
Author: Felix Kling,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-17 12:34:22

Puede requerir.archivos json.

var parsedJSON = require('./file-name');

Por ejemplo, si tiene un archivo config.json en el mismo directorio que su archivo de código fuente, usaría:

var config = require('./config.json');

O (se puede omitir la extensión del archivo):

var config = require('./config');

tenga en cuenta que require es síncrono y solo lee el archivo una vez , las siguientes llamadas devuelven el resultado de la caché

También tenga en cuenta que solo debe usar esto para archivos locales bajo su control absoluto, ya que potencialmente ejecuta cualquier código dentro del archivo.

 628
Author: eliocs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-02 12:16:43

Puede utilizar JSON.parse().

Debería poder usar el objeto JSON en cualquier implementación de JavaScript compatible con ECMAScript 5. Y V8 , sobre qué Nodo.js está construido es uno de ellos.


Analizar una cadena que contiene datos JSON

var str = '{ "name": "John Doe", "age": 42 }';
var obj = JSON.parse(str);

Analizar un archivo que contiene datos JSON

Tendrás que hacer algunas operaciones de archivo con el módulo fs.

Versión Asíncrona

var fs = require('fs');

fs.readFile('/path/to/file.json', 'utf8', function (err, data) {
    if (err) throw err; // we'll not consider error handling for now
    var obj = JSON.parse(data);
});

Síncrono versión

var fs = require('fs');
var json = JSON.parse(fs.readFileSync('/path/to/file.json', 'utf8'));

Quieres usar require? ¡Piénsalo de nuevo!

Usted puede utilizar a veces require:

var obj = require('path/to/file.json');

Pero, no recomiendo esto por varias razones:{[34]]}

Nota: Si está utilizando un archivo JSON para almacenar información confidencial (por ejemplo, contraseñas), esa es la forma incorrecta de hacerlo. Vea cómo Heroku lo hace: https://devcenter.heroku.com/articles/config-vars#setting-up-config-vars-for-a-deployed-application. Descubra cómo su plataforma lo hace, y usa process.env para recuperar los vars de configuración desde dentro del código.

  1. require es síncrona. Si tienes un archivo JSON muy grande, estrangulará tu bucle de eventos. Realmente necesitas usar JSON.parse con fs.readFile.
  2. require lea el archivo sólo una vez. Las llamadas posteriores a require para el mismo archivo devolverán una copia en caché. No es una buena idea si desea leer un archivo .json que se actualiza continuamente. Podrías usar un hack. Pero en este punto, es más fácil simplemente usar fs.
  3. Si su archivo no tiene una extensión .json, require no tratará el contenido del archivo como JSON.

En Serio! Uso JSON.parse.


load-json-file módulo

Si está leyendo un gran número de archivos .json (y si es extremadamente perezoso), se vuelve molesto escribir código repetitivo cada vez. Puede guardar algunos caracteres utilizando el load-json-file módulo.

const loadJsonFile = require('load-json-file');

Versión Asíncrona

loadJsonFile('/path/to/file.json').then(json => {
    // `json` contains the parsed object
});

Versión síncrona

let obj = loadJsonFile.sync('/path/to/file.json');

Analizando JSON de flujos

Si el contenido JSON se transmite a través de la red, debe usar un analizador de JSON de transmisión. De lo contrario, atará su procesador y ahogará su bucle de eventos hasta que el contenido JSON se transmita por completo.

Hay muchos paquetes disponibles en NPM para esto. Elige lo que es mejor para ti.


Error Manipulación / Seguridad

Si no está seguro de si lo que se pasa a JSON.parse() es JSON válido, asegúrese de incluir la llamada a JSON.parse() dentro de un bloque try/catch. Un usuario proporcionado cadena JSON podría bloquear su aplicación, e incluso podría conducir a agujeros de seguridad. Asegúrese de que el manejo de errores se realiza si analiza JSON proporcionado externamente.

 291
Author: Krumia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-09 03:02:56

Utilice el objeto JSON :

JSON.parse(str);
 79
Author: Mark Kahn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-12 17:54:28

Otro ejemplo de JSON.parse:

var fs = require('fs');
var file = __dirname + '/config.json';

fs.readFile(file, 'utf8', function (err, data) {
  if (err) {
    console.log('Error: ' + err);
    return;
  }

  data = JSON.parse(data);

  console.dir(data);
});
 33
Author: pyprism,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-24 09:15:49

Me gustaría mencionar que hay alternativas al objeto JSON global. JSON.parse y JSON.stringify son ambos síncronos, por lo que si desea tratar con objetos grandes, es posible que desee revisar algunos de los módulos JSON asíncronos.

Echa un vistazo: https://github.com/joyent/node/wiki/Modules#wiki-parsers-json

 32
Author: Haider,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-29 07:17:35

Incluye la biblioteca node-fs.

var fs = require("fs");
var file = JSON.parse(fs.readFileSync("./PATH/data.json", "utf8"));

Para obtener más información sobre la biblioteca 'fs', consulte la documentación en http://nodejs.org/api/fs.html

 28
Author: Abhishek Verma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-25 07:02:23

Dado que no sabes que tu cadena es realmente válida, lo pondría primero en un try catch. Además, dado que los bloques try catch no están optimizados por nodo, pondría todo en otra función:

function tryParseJson(str) {
    try {
        return JSON.parse(str);
    } catch (ex) {
        return null;
    }
}

O en"estilo asíncrono"

function tryParseJson(str, callback) {
    process.nextTick(function () {
      try {
          callback(null, JSON.parse(str));
      } catch (ex) {
          callback(ex)
      }
    })
}
 9
Author: Vlad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-26 16:48:29

¿Analizando una secuencia JSON? Utilizar JSONStream.

var request = require('request')
  , JSONStream = require('JSONStream')

request({url: 'http://isaacs.couchone.com/registry/_all_docs'})
    .pipe(JSONStream.parse('rows.*'))
    .pipe(es.mapSync(function (data) {
      return data
    }))

Https://github.com/dominictarr/JSONStream

 8
Author: Burcu Dogan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-10 09:54:48
JSON.parse("your string");

Eso es todo.

 7
Author: debianmaster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-10 14:37:36

Como otras respuestas aquí han mencionado, probablemente desee requerir un archivo json local que sepa que es seguro y presente, como un archivo de configuración:

var objectFromRequire = require('path/to/my/config.json'); 

O para usar el objeto JSON global para analizar un valor de cadena en un objeto:

var stringContainingJson = '\"json that is obtained from somewhere\"';
var objectFromParse = JSON.parse(stringContainingJson);

Tenga en cuenta que cuando se requiere un archivo se evalúa el contenido de ese archivo, lo que introduce un riesgo de seguridad en caso de que no sea un archivo json, sino un archivo js.

Aquí, he publicado una demo donde puedes ver ambos métodos y jugar con ellos en línea (el ejemplo de análisis está en app.archivo js-a continuación, haga clic en el botón ejecutar y ver el resultado en el terminal): http://staging1.codefresh.io/labs/api/env/json-parse-example

Puede modificar el código y ver el impacto...

 6
Author: nathan g,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-06 08:17:38

Todos aquí han hablado de JSON.analizar, así que pensé en decir algo más. Hay un gran módulo Connect con muchos middleware para hacer el desarrollo de aplicaciones más fácil y mejor. Uno de los middleware es bodyParser . Analiza JSON, formularios html, etc. También hay un middleware específico para analizar JSON solo noop.

Echa un vistazo a los enlaces de arriba, podría ser muy útil para usted.

 5
Author: Saransh Mohapatra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-05 05:10:49

Mi solución:

var fs = require('fs');
var file = __dirname + '/config.json';

fs.readFile(file, 'utf8', function (err, data) {
    if (err) {
        console.log('Error: ' + err);
        return;
    }

    data = JSON.parse(data);

    console.dir(data);
});
 4
Author: Ravindra Galav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-22 19:06:09

Solo quiero completar la respuesta (ya que luché con ella durante un tiempo), quiero mostrar cómo acceder a la información json, este ejemplo muestra el acceso a la matriz Json:

var request = require('request');
request('https://server/run?oper=get_groups_joined_by_user_id&user_id=5111298845048832', function (error, response, body) {
  if (!error && response.statusCode == 200) {
    var jsonArr = JSON.parse(body);
    console.log(jsonArr);
    console.log("group id:" + jsonArr[0].id);
  }
})
 4
Author: Eli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-31 09:49:08

Uso de JSON para su configuración con Node.js? Lea esto y obtenga sus habilidades de configuración de más de 9000...

Nota: Las personas que afirman que data = require ('./datos.json'); es un riesgo de seguridad y rechazo de las respuestas de las personas con celo: Estás exacta y completamente incorrecto. Intente colocar un archivo que no sea JSON en ese archivo... Node te dará un error, exactamente como lo haría si hicieras lo mismo con el mucho más lento y es más difícil codificar el archivo manual leído y luego el siguiente JSON.analizar(). Por favor, dejen de difundir información errónea; están lastimando al mundo, no ayudando. Nodo diseñado para permitir esto; no es un riesgo de seguridad!

Vienen las aplicaciones adecuadas 3+ capas de configuración:

  1. Configuración del servidor/contenedor
  2. Configuración de la aplicación
  3. (opcional) Configuración de inquilino/Comunidad/Organización
  4. Usuario config

La mayoría de los desarrolladores tratan la configuración de su servidor y aplicación como si pudiera cambiar. No puede. Puedes cambiar la capa de capas superiores una encima de la otra, pero estás modificando los requisitos básicos. Algunas cosas necesitan para existir! Haz que tu configuración actúe como si fuera inmutable, porque parte de ella básicamente lo es, al igual que tu código fuente.

Al no ver que muchas de sus cosas no van a cambiar después del inicio, conduce a anti-patrones como ensuciando su carga de configuración con bloques try / catch, y fingiendo que puede continuar sin su aplicación de configuración adecuada. Si puedes, eso pertenece a la capa de configuración de comunidad/usuario, no a la capa de configuración de servidor/aplicación. Lo estás haciendo mal. Las cosas opcionales deben ser capas en la parte superior cuando la aplicación termina es bootstrap.

Deja de golpear tu cabeza contra la pared: Tu configuración debe ser ultra simple.

Echa un vistazo a lo fácil que es es configurar algo tan complejo como un marco de servicio independiente del protocolo y de la fuente de datos utilizando un simple archivo de configuración json y una aplicación simple.archivo js...

Container-config.js...

{
    "service": {
        "type"  : "http",
        "name"  : "login",
        "port"  : 8085
    },
    "data": {
        "type"  : "mysql",
        "host"  : "localhost",
        "user"  : "notRoot",
        "pass"  : "oober1337",
        "name"  : "connect"
    }
}

Índice.js... (el motor que lo alimenta todo)

var config      = require('./container-config.json');       // Get our service configuration.
var data        = require(config.data.type);            // Load our data source plugin ('npm install mysql' for mysql).
var service     = require(config.service.type);         // Load our service plugin ('http' is built-in to node).
var processor   = require('./app.js');                  // Load our processor (the code you write).

var connection  = data.createConnection({ host: config.data.host, user: config.data.user, password: config.data.pass, database: config.data.name });
var server      = service.createServer(processor);
connection.connect();
server.listen(config.service.port, function() { console.log("%s service listening on port %s", config.service.type, config.service.port); });

App.js... (el código que alimenta su servicio agnóstico de protocolo y agnóstico de origen de datos)

module.exports = function(request, response){
    response.end('Responding to: ' + request.url);
}

Usando este patrón, ahora puede cargar cosas de configuración de la comunidad y el usuario en la parte superior de su aplicación arrancada, dev ops está listo para empujar su trabajo en un contenedor y escalarlo. Estás leído para multitenant. Userland está aislado. Ahora puede separar las preocupaciones de qué protocolo de servicio está utilizando, qué tipo de base de datos está utilizando, y simplemente centrarse en escribir buen código.

Debido a que está utilizando capas, puede confiar en una sola fuente de verdad para todo, en cualquier momento (el objeto de configuración en capas), y evitar comprobaciones de errores en cada paso, preocupándose por " oh mierda, ¿cómo voy a ¿hacer que este funcione sin la configuración adecuada?!?".

 4
Author: Nick Steele,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-08 17:58:58

Solo para hacer esto lo más complicado posible, y traer tantos paquetes como sea posible...

const fs = require('fs');
const bluebird = require('bluebird');
const _ = require('lodash');
const readTextFile = _.partial(bluebird.promisify(fs.readFile), _, {encoding:'utf8',flag:'r'});
const readJsonFile = filename => readTextFile(filename).then(JSON.parse);

Esto te permite hacer:

var dataPromise = readJsonFile("foo.json");
dataPromise.then(console.log);

O si estás usando async/await:

let data = await readJsonFile("foo.json");

La ventaja sobre el simple uso de readFileSync es que su servidor de nodos puede procesar otras solicitudes mientras el archivo se lee fuera del disco.

 3
Author: mpen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-03 21:52:28

Si desea agregar algunos comentarios en su JSON y permitir comas finales, puede usar la implementación siguiente:

var fs = require('fs');

var data = parseJsData('./message.json');

console.log('[INFO] data:', data);

function parseJsData(filename) {
    var json = fs.readFileSync(filename, 'utf8')
        .replace(/\s*\/\/.+/g, '')
        .replace(/,(\s*\})/g, '}')
    ;
    return JSON.parse(json);
}

Tenga en cuenta que podría no funcionar bien si tiene algo como "abc": "foo // bar" en su JSON. Entonces YMMV.

 3
Author: Nux,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-10 13:52:36

JSON.parse no garantizará la seguridad de la cadena json que está analizando. Deberías mirar una biblioteca como json-safe-parse o una biblioteca similar.

Desde la página npm de json-safe-parse:

JSON.parse es genial, pero tiene un grave defecto en el contexto de JavaScript: le permite anular propiedades heredadas. Esto puede convertirse en un problema si está analizando JSON desde una fuente no confiable (por ejemplo: un usuario), y llamando a funciones en él que esperaría que existieran.

 2
Author: Timothy C. Quinn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-20 20:58:53

Aproveche la función attempt de Lodash para devolver un objeto de error, que puede manejar con la función isError.

// Returns an error object on failure
function parseJSON(jsonString) {
   return _.attempt(JSON.parse.bind(null, jsonString));
}


// Example Usage
var goodJson = '{"id":123}';
var badJson = '{id:123}';
var goodResult = parseJSON(goodJson);
var badResult = parseJSON(badJson);

if (_.isError(goodResult)) {
   console.log('goodResult: handle error');
} else {
   console.log('goodResult: continue processing');
}
// > goodResult: continue processing

if (_.isError(badResult)) {
   console.log('badResult: handle error');
} else {
   console.log('badResult: continue processing');
}
// > badResult: handle error
 2
Author: l3x,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-04 23:14:38

Asegúrese siempre de usar JSON.parse in try catch block as node siempre arroja un error inesperado si tienes algunos datos dañados en tu json, así que usa este código en lugar de JSON simple.Parse

try{
     JSON.parse(data)
}
catch(e){
   throw new Error("data is corrupted")
  }
 2
Author: Rahul Kamboj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-25 07:01:00
var array={
    Action: 'Login',
    ErrorCode: 3,
    Detail: 'Your account not found.'
};
var http=require('http'),
    PORT=8789,
    server=function(req,res){
        res.writeHead(200,{'Content-Type':'application/json'});

        // JSON
        res.end(JSON.stringify(array));
    }

http.createServer(server).listen(PORT);
console.log('Server started.');
 1
Author: vuhung3990,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-20 03:21:55

Si el archivo fuente JSON es bastante grande, puede considerar la ruta asincrónica a través del enfoque async / await nativo con Node.js 8.0 como sigue

const fs = require('fs')

const fsReadFile = (fileName) => {
    fileName = `${__dirname}/${fileName}`
    return new Promise((resolve, reject) => {
        fs.readFile(fileName, 'utf8', (error, data) => {
            if (!error && data) {
                resolve(data)
            } else {
                reject(error);
            }
        });
    })
}

async function parseJSON(fileName) {
    try {
        return JSON.parse(await fsReadFile(fileName));
    } catch (err) {
        return { Error: `Something has gone wrong: ${err}` };
    }
}

parseJSON('veryBigFile.json')
    .then(res => console.log(res))
    .catch(err => console.log(err))
 1
Author: Lae Kettavong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-24 15:57:27

Esto tuvo que ser gritado a mí: solo funciona para archivos .json.

¡Si la terminación del archivo es diferente, esto no funciona!

 0
Author: Sebastian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-30 22:20:38

Puede usar JSON.parse () (que es una función incorporada que probablemente te obligará a envolverla con instrucciones try-catch).

O use alguna biblioteca npm de análisis JSON, algo así como json-parse-o

 0
Author: C'estLaVie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-08 20:39:23

Utilice esto para estar en el lado seguro

Var data = JSON.parse (Buffer.concat (arr).toString ());

 0
Author: Victor Michael Kosgei,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-14 18:39:36

Use JSON.parse (str);

Saber más - JSON.analizar()

Ejemplo -

var jsonStr = '{"result":true, "count":42}';

obj = JSON.parse(jsonStr);

console.log(obj.count);    //expected output: 42
console.log(obj.result);   // expected output: true
 0
Author: Praveen Poonia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-01 04:54:29

No es necesario requerir más módulos.
Sólo uso
var parsedObj = JSON.parse(yourObj);
No creo que haya problemas de seguridad con respecto a esto

 0
Author: Sachin S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-13 10:22:16

Es simple, puede convertir JSON a cadena usando JSON.stringify(json_obj), y convertir cadena a JSON usando JSON.parse("your json string").

 -1
Author: 00imvj00,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-16 03:08:28
var fs = require('fs');

fs.readFile('ashish.json',{encoding:'utf8'},function(data,err) {

   if(err) 
      throw err;

   else {

   console.log(data.toString());

 }
})
 -1
Author: ranjanah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-05 23:14:53