JavaScriptを使用して改行文字を含むJSON文字列をエスケープする方法


166

値が改行文字を持つJSON文字列を形成する必要があります。これはエスケープして、AJAX呼び出しを使用してポストする必要があります。JavaScriptで文字列をエスケープする方法を誰でも提案できますか?私はjQueryを使用していません。


1
改行文字\ nを\\ nにエスケープしてみました。正常に動作しています。しかし、すべてのエスケープ文字に対してこれを実行できるJSライブラリを探しています。
Srikant、2010年

1
JSON内の改行をエスケープする必要があるのはなぜですか?適切な解決策は関連するエンコード関数を使用することであるため、これらの値が使用されるときにどのようにデコードされるか
zzzzBov 2013年

私は6時間かけてさまざまなバリエーションを試してあらゆる種類のものを試し、小さな追加のスラッシュがすべて魔法のように機能することを発見しました。 .omg
Muhammad

1
サーバー側のphp-db-savingでAjax呼び出しを使用する場合は、php-functionのaddlashes()を使用して変換します。このソリューションでは、変換する場所が1つだけあり、javascript-replace行よりもクリーンです。
Marcel Ennix、2015

回答:


134

あなたのJSONと.stringify()それを取る。そして、使用.replace()方法をとのすべての出現置き換える\nとします\\n

編集:

私の知る限り、文字列内のすべての特殊文字をエスケープするためのよく知られたJSライブラリはありません。ただし、.replace()メソッドをチェーンして、次のようにすべての特殊文字を置き換えることができます。

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. 

しかし、それはかなり厄介ですね。コードを細かく分割し、スクリプトのメインフローをクリーンな状態に保ち、8つの連鎖.replace()呼び出しがないようにすることで、関数の美しさを入力してください。その機能をと呼ばれる関数に入れましょうescapeSpecialChars()。それではprototype chainStringオブジェクトのにアタッチして、escapeSpecialChars()Stringオブジェクトを直接呼び出すことができるようにします。

そのようです:

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

この関数を定義すると、コードの本体は次のように簡単になります。

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

3
アレックス、ありがとう。私はすべてのエスケープ文字に対してこれを行わなければなりませんか?これを行うJSライブラリはありますか?
Srikant、2010年

2
これは私の問題を解決した正確な関数ですString.prototype.escapeSpecialChars = function(){return this.replace(/ \\ / g、 "\\\\")。replace(/ \ n / g、 "\\ n")。replace(/ \ r / g、 "\\ r")。replace(/ \ t / g、 "\\ t")。replace(/ \ f / g、 "\\ f")。replace(/ "/ g、" \\\ "")。replace(/ '/ g、 "\\\'")。replace(/ \&/ g、 "\\&"); }
Srikant

10
user667073の回答にあるように、このソリューションにはいくつかのエラーがあります。json.orgを参照してください-&と ' エスケープしてはいけません。
Alexander Klimetschek

5
正規表現が間違っているようなので、私はこれに反対票を投じなければなりませんでした。使用しようとしましたが、スラッシュの1つを削除して正規表現を修正する必要がありました。たとえば、/ \\ n / gは/ \ n / gにする必要があります。詳細については、このリンクの「印刷できない文字」を参照してください-RegExp Info
b01

1
\自体はどうですか?それもエスケープする必要がありますか?
arash moeen 14

65

user667073が提案したとおり、バックスラッシュの置換を最初に並べ替え、引用の置換を修正する

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

3
これらすべてを実行する必要はありません。バックスラッシュ、改行、改行、および2つの引用符のみ。そして、それが欠けています:一重引用符、Line separator \u2028そしてParagraph separator \u2029。参照:es5.github.io/#x7.3
Ariel

1
いいですが、なぜ角かっこが必要であり、必要ではありません: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'); };
Johann Echavarria、2015年

3
完璧。受け入れられた回答(これより上)は単に機能しません。nodeJSを使用します。
Yossi Shasho

私はこのエラーを受け取ります:Uncaught SyntaxError: Unexpected token \ in JSON at position 2
Pathros

32

あなたと同じように、私はいくつかのコメントを調べ、htmlオブジェクトを含むJSONの特殊なエスケープ文字を置き換えるために投稿しています。

私の目的は、JSONオブジェクトの特殊文字を削除し、jsonオブジェクト内にあるhtmlをレンダリングすることです。

これが私がやったことであり、それが非常に簡単に使えることを願っています。

まず、jsonオブジェクトをJSON.stringifyし、結果をJSON.parseしました。

たとえば:

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

そしてそれは私の問題を解決し、純粋なJavascriptを使用して行われます。


4
これは間違いなく進むべき道です
Oz Lodriguez

1
これは間違いなく進むべき道です!
MartianE 2018年

1
これは間違いなくstackoverflowエラーで複雑で大きなオブジェクトで
壊れ

1
JSON.parse(JSON.stringify($("body")))本文といくつかのテーブルを含むhtmlファイルを試してください。$( "body")はJavaScriptオブジェクトですが、stringifyは解析に失敗します。
AaA 2018年

クエリを確認して元に戻します。
Balasubramani M 2018

24

アレックスからの答えは、少し控えめに言って、かなり間違っていると思います。

  • アレックスがエスケープしようとする一部の文字は、エスケープする必要がまったくありません(&や 'など)。
  • \ bはバックスペース文字ではなく、単語境界の一致です
  • エスケープが必要な文字は処理されません。

この機能

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

より良い近似のようです。


5
実際には、二重引用符の前にバックスラッシュを置き換えるように順序を変更する必要があります。そうしないと、\\\\ "になります。また、引用行は.replace(/ [\"] / g、 '\\\ "')
ライアン

10

単一引用符の小さな更新

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

7

これは古い投稿です。ただし、angular.fromJson、およびJSON.stringifyを使用している場合は、依然として役立つ場合があります。escape()は非推奨です。代わりにこれを使用して、

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


stringifyはすでにすべてのエスケープ処理を行っています-なぜそれを使用しないのか不思議です。git.io/vglq7
ベンデイビス

5

JSON.stringifyには2番目のパラメーターもあります。したがって、よりエレガントな解決策は次のとおりです。

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

これは古い質問ですが、すべてのケースを解決することはできなかったため、ソリューションはうまく機能しませんでした。私はついにここで仕事をした答えを見つけました

エスケープとエンコード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);
}

後で文字列を囲む二重引用符も削除しますか?escape = (string) -> JSON.stringify(string)[1...-1]
Radek 2013年


3

サーバー側のスクリプト言語がPHPの場合は json_encode()を使用しjson_encode()、改行やその他の予期しないトークンをエスケープします(PHPを使用していない場合は、スクリプト言語に類似した関数を探します)

その後$.parseJSON()、JavaScriptで使用します。


データをphpからjavascriptにJSON文字列として渡す場合、この答えを確認してください-ダブルエスケープは、JSON.parseを渡し、json文字列をオブジェクトに変換するのに役立ちました。 <script> windows.data_from_php = <?php echo json_encode(json_encode($arrayOrObjToJs)); ?>; var phpData = JSON.parse(windows.data_from_php); </script> php JSON.parse double encode
Vladimir Vukanac '19 / 11/14

2

JSONTextareaフィールドの改行が原因でエラーがスローされたAjax呼び出しの1 つでも、同じ状況が発生しました。ここで与えられた解決策は私にはうまくいきませんでした。だから私はJavaScriptの.escape機能を使用し、それはうまくいきました。次に、から値を取得するために、を使用してJSONエスケープを解除しました.unescape


Ajax呼び出しを使用して、php-function newStr = addlashes(str)を使用してから、dbに保存することを好みます。だから私はjavascript-(client)-sideで変換する必要はありません。このソリューションでは、スラッシュを変換する場所が1つだけ必要です。私はこのソリューションにとても満足しています。
Marcel Ennix、2015

2

組み込みのjQuery.serialize()を使用してtextareaから値を抽出し、入力をURLエンコードしました。重要な点は、すべての特殊文字を自分で検索して置き換える必要がないことと、改行を保持してHTMLをエスケープすることです。シリアライズが機能するためには、入力フィールドにname属性が必要であり、エスケープされた文字列に同じ属性を追加する必要があります。あなたが探しているものではないかもしれませんが、それは私にとってはうまくいきます。

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

1

Ajaxの任意の形式を使用する場合、CGIサーバーから受信した応答の形式に関する詳細なドキュメントがWeb上にないようです。ここでのいくつかのエントリは、jQueryによって自動的に実行されるか、JavascriptシステムまたはライブラリJSON解析を使用して手動で実行されるかに関係なく、返されたテキストまたはjsonデータの改行をエスケープしてJSON変換(おそらくキャッチされない例外をスローすることによって作成される)を回避する必要があることを指摘しています呼び出します。

プログラマーがこの問題を投稿するそれぞれのケースで、不十分な解決策が提示され(ほとんどの場合、送信側で\ nを\\ nに置き換える)、問題は取り除かれます。Windowsのパス名など、コントロールのエスケープシーケンスを誤って埋め込んだ文字列値を渡すと、それらの不適切さが明らかになります。例は "C:\ Chris \ Roberts.php"で、これには制御文字^ cおよび^ rが含まれているため、文字列{"file": "C:\ Chris \ Roberts.php"}のJSON変換が発生する可能性があります。永久にループします。そのような値を生成する1つの方法は、サーバーからクライアントにPHP警告およびエラーメッセージを意図的に渡そうとすることですが、これは合理的な考えです。

定義により、Ajaxは舞台裏でHTTP接続を使用します。このような接続は、GETとPOSTを使用してデータを渡します。どちらの場合も、制御文字を含む不正な構文を回避するために送信データをエンコードする必要があります。

これは、解決策と思われるものを構築するための十分なヒントを提供します(より多くのテストが必要です)。PHP(送信)側でrawurlencodeを使用してデータをエンコードし、Javascript(受信)側でエスケープを解除してデータをデコードします。これらをテキスト文字列全体に適用する場合もあれば、JSON内の値にのみ適用する場合もあります。

このアイデアが正しいことが判明した場合、すべてのレベルのプログラマーがこの問題を一度に解決できるように、簡単な例を作成できます。


0

これは本当に古代の投稿のようです:-)しかし、私がこれに対して最善の回避策である100%にするのは、複雑なコードなしで機能することです。base64へのエンコード/デコードの両方の機能を使用することです。これらはatob()とbtoa()です。はるかに簡単で最良の方法であり、エスケープする文字を逃した場合でも心配する必要はありません。

ジョージ


同じ解決策を思いついたので。誰かがこの解決策を明確にできるかどうか、そしていくつかの隠された警告があるかどうか私は思います。ありがとう。
mahish

0

Googleがここに着陸し続け、JSONの二重引用符がエスケープさ"{\"foo\": true}"れていない場合()にAPIがエラーをスローする場合、必要なのは2回文字列化することだけです。JSON.stringify(JSON.stringify(bar))


-1

文字列をエンコードするには、encodeURIComponent()を使用します。

例えば。var myEscapedJSONString = encodeURIComponent(JSON.stringify(myJSON));

Webサーバーが自動的に同じ処理を行うため、デコードする必要はありません。


-8

正規表現を使用しないでください(つまり、まったく使用しないようにします)。最善かつ効果的な方法:

String.prototype.escapeJSON = function() {
    var result = "";
    for (var i = 0; i < this.length; i++)
    {
        var ch = this[i];
        switch (ch)
        {
            case "\\": ch = "\\\\"; break;
            case "\'": ch = "\\'"; break;
            case "\"": ch = '\\"'; break;
            case "\&": ch = "\\&"; break;
            case "\t": ch = "\\t"; break;
            case "\n": ch = "\\n"; break;
            case "\r": ch = "\\r"; break;
            case "\b": ch = "\\b"; break;
            case "\f": ch = "\\f"; break;
            case "\v": ch = "\\v"; break;
            default: break;
        }

        result += ch;
    }

    return result;
};

「絶対に正規表現を使わないでください(決してまったく使わない)」とは言えません。すべてのツールがその目的を果たします。
zstate

あなたの答えは有効です、あなたは非常に独断的な方法でそれを表現しました、それは特にジュニアにとって混乱を引き起こすかもしれません。
zstate

@oncode正規表現は、いつどのように使用しても、信じられないほど役に立たないものです。未定義の動作につながり、CPU時間を浪費するだけです。
Alek Depler
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.