如何使用JavaScript对包含换行符的JSON字符串进行转义?


166

我必须形成一个JSON字符串,其中一个值具有换行符。必须对此进行转义,然后使用AJAX调用发布。任何人都可以提出一种使用JavaScript对字符串进行转义的方法。我没有使用jQuery。


1
我尝试将换行符\ n转义为\\ n。一切正常。但是我正在寻找可以对所有转义字符执行此操作的任何JS库。
Srikant

1
为什么需要在JSON中转义换行符?这些值在使用时如何解码,因为适当的解决方案是使用相关的编码功能。
zzzzBov

我花了6个小时尝试各种变化多样的事物,但发现一个小的斜线会使它像魔术一样工作,而我认为很难的事情却花了5分钟……我认为得到的东西变得不可能了。 .omg
Muhammad Umer

1
当您将Ajax调用与服务器端php-db-saving一起使用时,只需使用php-function addlashes()函数即可将其转换。使用此解决方案,您只有一个地方可以转换,而且比javascript-replace行更干净。
Marcel Ennix 2015年

Answers:


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 chain该的String对象,所以我们可以调用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

2
这是解决我的问题的确切函数String.prototype.escapeSpecialChars = function(){返回this.replace(/ \\ / g,“ \\\\”)。replace(/ \ n / g,“ \\ n”)。replace(/ \ r / g,“ \\ r”)。replace(/ \ t / g,“ \\ t”)。replace(/ \ f / g,“ \\ f”)。replace(/“ / g,” \\\“”)。replace(/'/ g,“ \\\'”)。替换(/ \&/ g,“ \\&”); }
Srikant

10
如user667073的答案所述,此解决方案中存在一些错误。请参阅json.org-&和' 不得转义。
2011年

5
由于正则表达式似乎是错误的,因此我不得不投票反对。我尝试使用它,但必须通过删除其中一个斜杠来修复正则表达式,例如:/ \\ n / g应该为/ \ n / g。有关详细信息
请参见此

1
\本身呢?应该也逃脱吗?
arash moeen

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
您不必全部做这些。仅反斜杠,换行符,换行符和两个引号。而且它缺少:单引号Line separator \u2028Paragraph 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

3
完善。接受的答案(在此之上)根本行不通。使用nodeJS。
Yossi Shasho

我收到此错误:Uncaught SyntaxError: Unexpected token \ in JSON at position 2
Pathros

31

像您一样,我一直在研究一些评论并发表文章,以替换其中包含html对象的JSON中的特殊转义符。

我的对象是删除JSON对象中的特殊字符,并呈现json对象内部的html。

这是我所做的,希望它非常易于使用。

首先,我做了JSON.stringify我的json对象,并JSON.parse结果。

例如:

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

它解决了我的问题,并使用Pure Javascript完成。


4
这绝对是必经之路
Oz Lodriguez '16

1
这绝对是要走的路!
MartianE '18 -10-1

1
这肯定会在复杂的大型对象上stackoverflow出错而
损坏

1
尝试JSON.parse(JSON.stringify($("body")))使用带有正文和一些表格的html文件。$(“ body”)是一个javascript对象,但stringify解析失败。
AaA

我将检查您的查询并还原。
Balasubramani M

24

坦率地说,我怕说亚历克斯给出的答案是不正确的:

  • Alex尝试转义的某些字符根本不需要转义(例如&和');
  • \ 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,'\\\ “')
瑞安(Ryan

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.

参考http://www.w3schools.com/jsref/jsref_decodeuricomponent.asp


stringify已经为您完成了所有的转义操作-我很好奇为什么不只使用它呢?git.io/vglq7
Ben Davis

5

JSON.stringify上还有第二个参数。因此,更优雅的解决方案是:

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中使用,完成!


如果将数据作为JSON字符串从php传递到javascript,请检查此答案-两次转义,帮助我传递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双重编码
Vladimir Vukanac

2

我在一个Ajax调用中遇到了相同的情况,JSON由于Textarea字段中的换行符,该错误引发了错误。这里给出的解决方案对我不起作用。所以我使用了Javascript的.escape功能,效果很好。然后从中检索值JSON,我只是使用进行了转义.unescape


使用Ajax调用,我更喜欢使用php函数newStr = addslashes(str),然后保存到db。因此,我不必在javascript-(客户端)端进行转换。使用此解决方案,您只需要一个位置即可转换斜线。我对此解决方案非常满意。
Marcel Ennix 2015年

2

我使用内置的jQuery.serialize()从文本区域中提取值来对输入进行urlencode。优点是您不必自行搜索替换所有特殊字符,而且我还保留换行符并转义html。为了使序列化工作,输入字段似乎需要具有name属性,并且还向转义的字符串添加了相同的属性,需要将其替换掉。可能不是您要找的东西,但它对我有用。

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

1

当使用任何形式的Ajax时,Web上似乎缺少有关从CGI服务器接收到的响应格式的详细文档。这里的一些条目指出,必须转义返回的文本或json数据中的换行符,以防止JSON转换中的无限循环(挂起)(可能是通过引发未捕获的异常而创建),无论是由jQuery自动完成还是使用Javascript系统或库JSON解析手动完成电话。

在程序员发布此问题的每种情况下,都会出现解决方案不充分的情况(最常见的是在发送方用\\ n替换\ n),此事就丢了。当传递意外嵌入控件转义序列的字符串值(例如Windows路径名)时,就会显示出它们的不足。一个示例是“ C:\ Chris \ Roberts.php”,其中包含控制字符^ c和^ r,这可能导致将字符串{“ file”:“ C:\ Chris \ Roberts.php”}进行JSON转换为永远循环。生成此类值的一种方法是故意尝试将PHP警告和错误消息从服务器传递到客户端,这是一个合理的想法。

根据定义,Ajax在后台使用HTTP连接。这样的连接使用GET和POST传递数据,这两者都需要对发送的数据进行编码,以避免语法错误,包括控制字符。

这足以构造一个似乎是解决方案的提示(需要更多测试):在PHP(发送)侧使用rawurlencode编码数据,而在Javascript(接收)侧使用unscape解码数据。在某些情况下,您会将它们应用于整个文本字符串,在其他情况下,仅将它们应用于JSON中的值。

如果这个想法是正确的,那么可以构造一些简单的示例来帮助各个级别的程序员一劳永逸地解决这个问题。


0

看起来这确实是一个古老的帖子:-)但是,伙计们,我对此的最佳解决方法是,在没有复杂代码的情况下100%工作,是同时使用对base64的编码/解码功能。它们是atob()和btoa()。到目前为止,最简单,最好的方法是,不必担心是否错过了要转义的字符。

乔治


自从我提出了相同的解决方案。我想知道是否有人可以澄清此解决方案,而后又有一些隐藏的警告。谢谢。
mahish

0

如果您的Google不断将您降落在这里,并且您的api抛出错误,除非对您的JSON双引号进行了转义("{\"foo\": true}"),那么您需要做的是两次字符串化,例如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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.