¿Cómo escapar una cadena JSON que contiene caracteres de nueva línea usando JavaScript?


Tengo que formar una cadena JSON en la que un valor tenga un carácter de línea nuevo. Esto tiene que ser escapado y luego publicado usando llamada AJAX. Puede alguien sugerir una manera de escapar de la cadena con JavaScript. No estoy usando jQuery.

Author: Brett DeWoody, 2010-11-23

13 answers

Toma tu JSON y .stringify() él. Luego use el método .replace() y reemplace todas las ocurrencias de \n con \\n.

EDITAR:

Por lo que sé, no hay bibliotecas JS bien conocidas para escapar todos los caracteres especiales en una cadena. Pero, puedes encadenar el método .replace() y reemplazar todos los caracteres especiales de esta manera:

var myJSONString = JSON.stringify(myJSON);
var myEscapedJSONString = myJSONString.replace(/\\n/g, "\\n")
                                      .replace(/\\'/g, "\\'")
                                      .replace(/\\"/g, '\\"')
                                      .replace(/\\&/g, "\\&")
                                      .replace(/\\r/g, "\\r")
                                      .replace(/\\t/g, "\\t")
                                      .replace(/\\b/g, "\\b")
                                      .replace(/\\f/g, "\\f");
// myEscapedJSONString is now ready to be POST'ed to the server. 

Pero eso es bastante desagradable, ¿no? Introduzca la belleza de las funciones, ya que le permiten romper el código en pedazos y mantener la principal flujo de su script limpio, y libre de 8 llamadas encadenadas .replace(). Así que vamos a poner esa funcionalidad en una función llamada, escapeSpecialChars(). Vamos a seguir adelante y adjuntarlo al prototype chain del objeto String, para que podamos llamar a escapeSpecialChars() directamente en objetos String.

Así:

String.prototype.escapeSpecialChars = function() {
    return this.replace(/\\n/g, "\\n")
               .replace(/\\'/g, "\\'")
               .replace(/\\"/g, '\\"')
               .replace(/\\&/g, "\\&")
               .replace(/\\r/g, "\\r")
               .replace(/\\t/g, "\\t")
               .replace(/\\b/g, "\\b")
               .replace(/\\f/g, "\\f");
};

Una vez que hemos definido esa función, el cuerpo principal de nuestro código es tan simple como esto: {[14]]}

var myJSONString = JSON.stringify(myJSON);
var myEscapedJSONString = myJSONString.escapeSpecialChars();
// myEscapedJSONString is now ready to be POST'ed to the server
 119
Author: Alex,
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-16 19:59:45

Según user667073 sugerido, excepto reordenar el reemplazo de la barra invertida primero, y arreglar el reemplazo de la cita

escape = function (str) {
  return str
    .replace(/[\\]/g, '\\\\')
    .replace(/[\"]/g, '\\\"')
    .replace(/[\/]/g, '\\/')
    .replace(/[\b]/g, '\\b')
    .replace(/[\f]/g, '\\f')
    .replace(/[\n]/g, '\\n')
    .replace(/[\r]/g, '\\r')
    .replace(/[\t]/g, '\\t');
};
 60
Author: Ryan,
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-02-26 22:49:33

Al igual que usted, he estado buscando en varios comentarios y post para reemplazar caracteres de escape especiales en mi JSON que contiene objeto html dentro de eso.

Mi objetivo es eliminar los caracteres especiales en el objeto JSON y también representar el html que está dentro del objeto json.

Esto es lo que hice y espero que sea muy fácil de usar.

Primero hice JSON.stringify mi objeto json y JSON.analiza el resultado.

Por ejemplo:

JSON.parse(JSON.stringify(jsonObject));

Y resuelve mi problema y hecho usando Javascript puro.

 23
Author: Balasubramani M,
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-02-15 15:44:56

Me temo que decir que la respuesta dada por Alex es bastante incorrecta, por decirlo suavemente:

  • Algunos personajes que Alex intenta escapar no necesitan ser escapados en absoluto (como & and');
  • \b no es en absoluto el carácter de retroceso, sino más bien una coincidencia de límite de palabra
  • Los caracteres que se requieren para escapar no se manejan.

Esta función

escape = function (str) {
    // TODO: escape %x75 4HEXDIG ?? chars
    return str
      .replace(/[\"]/g, '\\"')
      .replace(/[\\]/g, '\\\\')
      .replace(/[\/]/g, '\\/')
      .replace(/[\b]/g, '\\b')
      .replace(/[\f]/g, '\\f')
      .replace(/[\n]/g, '\\n')
      .replace(/[\r]/g, '\\r')
      .replace(/[\t]/g, '\\t')
    ; };

Parece ser una mejor aproximación.

 21
Author: whaefelinger,
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
2011-10-20 13:11:53

Una pequeña actualización para comillas simples

function escape (key, val) {
    if (typeof(val)!="string") return val;
    return val      
        .replace(/[\\]/g, '\\\\')
        .replace(/[\/]/g, '\\/')
        .replace(/[\b]/g, '\\b')
        .replace(/[\f]/g, '\\f')
        .replace(/[\n]/g, '\\n')
        .replace(/[\r]/g, '\\r')
        .replace(/[\t]/g, '\\t')
        .replace(/[\"]/g, '\\"')
        .replace(/\\'/g, "\\'"); 
}

var myJSONString = JSON.stringify(myJSON,escape);
 10
Author: Akash Dhawale,
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-01-03 11:38:39

Este es un post antiguo. pero aún puede ser útil para aquellos que usan angular.De Json, y JSON.stringify. escape() está obsoleto. use esto en su lugar,

var uri_enc = encodeURIComponent(uri); //before you post the contents
var uri_dec = decodeURIComponent(uri_enc); //before you display/use the contents.

Ref http://www.w3schools.com/jsref/jsref_decodeuricomponent.asp

 6
Author: Sam,
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-26 03:31:35

También hay un segundo parámetro en JSON.stringify. Entonces, una solución más elegante sería:

function escape (key, val) {
    if (typeof(val)!="string") return val;
    return val
      .replace(/[\"]/g, '\\"')
      .replace(/[\\]/g, '\\\\')
      .replace(/[\/]/g, '\\/')
      .replace(/[\b]/g, '\\b')
      .replace(/[\f]/g, '\\f')
      .replace(/[\n]/g, '\\n')
      .replace(/[\r]/g, '\\r')
      .replace(/[\t]/g, '\\t')
    ; 
}

var myJSONString = JSON.stringify(myJSON,escape);
 5
Author: Krunoslav Djakovic,
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
2012-09-12 16:23:16

Esta es una vieja pregunta, pero la solución no funcionó bien para mí, ya que no resolvió todos los casos. Finalmente encontré una respuesta que hizo el trabajo aquí

Publicaré mi solución combinada de ambos usando escape y codificar el componente uri:

// implement JSON stringify serialization
JSON.stringify = JSON.stringify || function (obj) {
    var t = typeof (obj);
    if (t != "object" || obj === null) {
        // simple data type
        if (t == "string") obj = '"'+obj+'"';
        return String(obj);
    }
    else {
        // recurse array or object
        var n, v, json = [], arr = (obj && obj.constructor == Array);
        for (n in obj) {
            v = obj[n]; t = typeof(v);
            if (t == "string") v = '"'+v+'"';
            else if (t == "object" && v !== null) v = JSON.stringify(v);
            json.push((arr ? "" : '"' + n + '":') + String(v));
        }
        var rawString = (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
       return rawString;
    }
};
function escape (key, val) {
    if (typeof(val)!="string") return val;

    var replaced = encodeURIComponent(val);
    return replaced;
}

JSON.stringifyEscaped = function(obj){
    return JSON.stringify(obj,escape);
}
 4
Author: Mitzi,
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-05-23 10:31:16

Tuve la misma situación en una de mis llamadas Ajax, donde JSON estaba lanzando un error debido a la nueva línea en el campo Textarea. La solución dada aquí no funcionó para mí. Así que usé la función .escape de Javascript y funcionó bien. A continuación, para recuperar el valor de JSON, acabo de sin escape usando .unescape.

 2
Author: Anubhav Trivedi,
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-02-12 15:24:11

Cuando se utiliza cualquier forma de Ajax, la documentación detallada para el formato de las respuestas recibidas del servidor CGI parece carecer en la Web. Algunas entradas aquí señalan que las nuevas líneas en el texto devuelto o los datos json deben escaparse para evitar bucles infinitos (se cuelgan) en la conversión JSON (posiblemente creada lanzando una excepción no capturada), ya sea realizada automáticamente por jQuery o manualmente usando el sistema Javascript o la biblioteca de llamadas JSON de análisis.

En cada caso donde los programadores publican esto problema, se presentan soluciones inadecuadas (la mayoría de las veces reemplazando \n por \ \ n en el lado de envío) y el asunto se elimina. Su inadecuación se revela al pasar valores de cadena que incrustan accidentalmente secuencias de escape de control, como los nombres de ruta de Windows. Un ejemplo es "C:\Chris\Roberts.php", que contiene los caracteres de control ^c y ^r, que pueden causar la conversión JSON de la cadena {"file":"C:\Chris\Roberts.php"} para hacer un bucle para siempre. Una forma de generar tales valores es deliberadamente intentar pasar mensajes de advertencia y error de PHP del servidor al cliente, una idea razonable.

Por definición, Ajax utiliza conexiones HTTP entre bastidores. Tales conexiones pasan datos usando GET y POST, los cuales requieren codificar los datos enviados para evitar la sintaxis incorrecta, incluidos los caracteres de control.

Esto da una pista suficiente para construir lo que parece ser una solución (necesita más pruebas): usar rawurlencode en el lado de PHP (envío) para codificar los datos, y unescape en el Lado Javascript (recepción) para decodificar los datos. En algunos casos, los aplicará a cadenas de texto completas, en otros casos los aplicará solo a valores dentro de JSON.

Si esta idea resulta ser correcta, se pueden construir ejemplos simples para ayudar a los programadores en todos los niveles a resolver este problema de una vez por todas.

 1
Author: David Spector,
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-10-04 20:29:30

Use json_encode () si su lenguaje de scripting del lado del servidor es php, json_encode() escapa de la nueva línea y otros tokens inesperados para usted (si no es php, busque una función similar para su lan de scripting)

Luego use $.parseJSON () en tu javascript, hecho!

 1
Author: avngr,
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-18 05:53:44

Usé el jQuery integrado en .serialize () para extraer el valor de un área de texto a urlencode la entrada. La parte pro es que usted no tiene que buscar reemplazar cada char especial por su cuenta y también mantener las nuevas líneas y escapes html. Para que serialize funcione, parece que el campo de entrada necesita tener un atributo name y también agrega el mismo atributo a la cadena escapada que necesita ser reemplazada. Puede que no sea lo que estás buscando, pero funciona para mí.

var myinputfield = jQuery("#myinputfield"); 
var text = myinputfield.serialize();
text = text.replace(myinputfield.attr('name') + '=','');
 1
Author: Janspeed,
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-24 12:10:08

Parece que este es un post antiguo realmente :-) Pero chicos, la mejor solución que tengo para esto, para ser 100% que funciona sin código complicado, es usar ambas funciones de codificación/decodificación a base64. Estos son atob() y btoa(). Con mucho, la forma más fácil y mejor, no hay necesidad de preocuparse si se perdió algún personaje para escapar.

George

 1
Author: Giorgoc,
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-03-11 20:50:50