web-dev-qa-db-fra.com

Comment échapper à une chaîne JSON contenant des caractères de nouvelle ligne à l'aide de JavaScript?

Je dois former une chaîne JSON dans laquelle une valeur a un caractère de nouvelle ligne. Ceci doit être échappé puis posté en utilisant AJAX call. Quelqu'un peut-il suggérer un moyen d'échapper à la chaîne avec JavaScript? Je n'utilise pas jQuery.

140
Srikant

Prenez votre JSON et .stringify() le. Puis utilisez la méthode .replace() et remplacez toutes les occurrences de \n par \\n

MODIFIER:

Autant que je sache, il n'y a pas de bibliothèques JS bien connues pour échapper à tous les caractères spéciaux d'une chaîne. Mais vous pouvez enchaîner la méthode .replace() et remplacer tous les caractères spéciaux comme ceci:

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. 

Mais c'est assez méchant, n'est-ce pas? Entrez dans la beauté des fonctions, dans la mesure où elles vous permettent de diviser le code en morceaux et de garder le flux principal de votre script propre et exempt de 8 appels .replace() chaînés. Mettons donc cette fonctionnalité dans une fonction appelée escapeSpecialChars(). Attachons-le au prototype chain de l'objet String pour pouvoir appeler escapeSpecialChars() directement sur les objets String.

Ainsi:

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

Une fois que nous avons défini cette fonction, le corps de notre code est aussi simple que cela:

var myJSONString = JSON.stringify(myJSON);
var myEscapedJSONString = myJSONString.escapeSpecialChars();
// myEscapedJSONString is now ready to be POST'ed to the server
123
Alex

Conformément aux suggestions de l'utilisateur667073, à l'exception de la réorganisation en premier du remplacement de la barre oblique inversée et de la résolution du remplacement du devis.

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');
};
61
Ryan

Comme vous, j'ai examiné plusieurs commentaires et publié pour remplacer des caractères d'échappement spéciaux dans mon JSON, qui contient un objet html à l'intérieur. 

Mon objet est de supprimer les caractères spéciaux de l'objet JSON et de restituer le code HTML contenu dans l'objet Json.

Voici ce que j'ai fait et j'espère que c'est très simple à utiliser.

J'ai d'abord fait JSON.stringify mon objet json et json.parse le résultat.

Par exemple:

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

Et cela résout mon problème et fait en utilisant Pure Javascript.

24
Balasubramani M

J'ai peur de dire que la réponse donnée par Alex est plutôt incorrecte, pour le dire gentiment:

  • Certains personnages qu'Alex essaie d'échapper ne sont pas obligés de s'échapper (comme & and ');
  • \ b n'est pas du tout le caractère de retour arrière, mais plutôt une correspondance de limite de mot
  • Les caractères à échapper ne sont pas gérés.

Cette fonction 

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

semble être une meilleure approximation.

21
whaefelinger

Une petite mise à jour pour les guillemets 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
Akash Dhawale

c'est un ancien post. mais cela peut toujours être utile pour ceux qui utilisent angular.fromJson, et JSON.stringify . escape () est obsolète.

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
Sam

Il existe également un deuxième paramètre sur JSON.stringify. Donc, une solution plus élégante serait:

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
Krunoslav Djakovic

C'est une vieille question mais la solution n'a pas bien fonctionné pour moi car elle n'a pas résolu tous les cas. J'ai finalement trouvé une réponse qui a fait le travail ici

Je vais publier ma solution combinée utilisant à la fois d'échappement et le composant uri d'encodage:

// 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
Mitzi

J'ai eu la même situation dans l'un de mes appels Ajax, où JSON renvoyait une erreur en raison de la nouvelle ligne dans le champ Textarea. La solution donnée ici ne fonctionnait pas pour moi . J'ai donc utilisé la fonction .escape de Javascript et cela a bien fonctionné. Ensuite, pour récupérer la valeur de JSON, je viens d'échapper à l'aide de .unescape.

2
Anubhav Trivedi

J'ai utilisé le construit dans jQuery.serialize () pour extraire la valeur d'une zone de texte pour urlencoder l'entrée. La partie pro, c’est que vous n’avez pas à chercher, remplacez chaque caractère spécial par vous-même et je garde également les nouvelles lignes et échappe au code HTML. Pour que la sérialisation fonctionne, il semble que le champ d'entrée ait besoin d'un attribut name et ajoute également le même attribut à la chaîne d'échappement qui doit être remplacée. Peut-être pas ce que vous cherchez, mais cela fonctionne pour moi.

var myinputfield = jQuery("#myinputfield"); 
var text = myinputfield.serialize();
text = text.replace(myinputfield.attr('name') + '=','');
1
Janspeed

Lorsque vous utilisez une forme quelconque d'Ajax, la documentation détaillée relative au format des réponses reçues du serveur CGI semble faire défaut sur le Web. Certaines entrées soulignent que les retours à la ligne dans les données textuelles ou json renvoyées doivent être évités pour éviter les boucles infinies (blocage) lors de la conversion JSON (éventuellement créées en lançant une exception non capturée), qu'elles soient effectuées automatiquement par jQuery ou manuellement à l'aide du système Javascript ou de la bibliothèque. Analyse JSON appels.

Chaque fois que les programmeurs signalent ce problème, des solutions inadéquates sont présentées (le plus souvent en remplaçant\n par \\ n du côté de l'envoi) et la question est abandonnée. Leur inadéquation est révélée lors du passage de valeurs de chaîne qui incorporent accidentellement des séquences d'échappement de contrôle, telles que les noms de chemins Windows. Un exemple est "C:\Chris\Roberts.php", qui contient les caractères de contrôle ^ c et ^ r, ce qui peut provoquer la conversion JSON de la chaîne {"fichier": "C:\Chris\Roberts.php"} en boucle pour toujours. Une façon de générer de telles valeurs consiste à essayer délibérément de faire passer des messages d’avertissement et d’erreur PHP du serveur au client, une idée raisonnable.

Par définition, Ajax utilise des connexions HTTP en coulisse. De telles connexions transmettent des données à l'aide de GET et POST. Ces deux méthodes nécessitent le codage des données envoyées pour éviter une syntaxe incorrecte, y compris des caractères de contrôle.

Cela donne assez d’indices pour construire ce qui semble être une solution (il a besoin de plus de tests): utiliser rawurlencode du côté PHP (envoi) pour coder les données, et annuler la sortie du côté Javascript (réception) décoder les données. Dans certains cas, vous les appliquerez à des chaînes de texte entières. Dans d'autres cas, vous ne les appliquerez qu'aux valeurs contenues dans JSON.

Si cette idée s'avère correcte, des exemples simples peuvent être construits pour aider les programmeurs à tous les niveaux à résoudre ce problème une fois pour toutes.

1
David Spector

utilisez json_encode () si votre script côté script est lang, php,

utilisez ensuite $ .parseJSON () dans votre javascript, c'est fait!

1
avngr

Il vaut mieux utiliser JSON.parse(yourUnescapedJson);

0
Mohit Vachhani

Utilisez encodeURIComponent () pour encoder la chaîne.

Par exemple. var myEscapedJSONString = encodeURIComponent (JSON.stringify (myJSON));

Vous n'avez pas besoin de le décoder, car le serveur Web fait automatiquement la même chose.

0
Sanju Kaniyamattam

On dirait que c’est vraiment un article ancien :-) Mais les gars, la meilleure solution que j’ai pour cela, pour être à 100% que cela fonctionne sans code compliqué, est d’utiliser les deux fonctions d’encodage/décodage en base64. Ce sont atob () et btoa (). De loin le moyen le plus simple et le meilleur, inutile de vous inquiéter si vous avez manqué des personnages à échapper.

George

0
Giorgoc