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

我必须形成一个JSON字符串,其中一个值有新的行字符。这必须转义,然后使用AJAX调用发布。谁能建议一种用JavaScript转义字符串的方法?我没有使用jQuery。

459692 次浏览

取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()的函数中。让我们继续将它附加到String对象的prototype chain,这样我们就可以直接在String对象上调用escapeSpecialChars()

像这样:

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

恕我直言,Alex给出的答案是不正确的,婉转地说:

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

似乎是一个更好的近似。

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

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

单引号的一个小更新

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);
我在我的一个Ajax调用中得到了相同的情况,其中JSON由于Textarea字段中的换行符而抛出错误。这里给出的解决方案对我没用。 所以我使用Javascript的.escape函数,它工作得很好。然后,为了从JSON中检索值,我只是使用.unescape进行了未转义

这是一个老问题,但这个解决方案对我来说并不是很有效,因为它并没有解决所有的情况。我终于找到一个答案,做的工作在这里

我将发布使用escape和encode 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);
}

在使用任何形式的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(接收)端使用unescape来解码数据。在某些情况下,您将把它们应用于整个文本字符串,在其他情况下,您将只应用于JSON中的值。

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

如果您的服务器端脚本是PHP,则使用json_encode ()json_encode()转义换行&其他意想不到的礼物 (如果不使用PHP,请为您的脚本语言寻找类似的函数)

然后在JavaScript中使用$.parseJSON(),完成!

这是一个老帖子。但对于那些使用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

我使用内置的jQuery.serialize ()从文本区域提取值,以urlencode输入。专业的部分是,你不需要搜索替换每一个特殊的字符在你自己和我也保持换行符和转义html。为了序列化工作,似乎输入字段需要有一个name属性,但它也添加了相同的属性转义字符串,需要被替换掉。也许不是你想要的,但对我有用。

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

像你一样,我一直在寻找一些评论和帖子来替换我的JSON中包含html对象的特殊转义字符。

我的对象是删除JSON对象中的特殊字符,并渲染JSON对象内部的html。

以下是我所做的,希望使用起来非常简单。

首先我使用了JSON。stringify我的json对象和json。解析结果。

如:

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

它解决了我的问题,并使用纯Javascript。

看起来这真的是一个古老的帖子:-)但是伙计们,我对此最好的解决办法,是100%的工作,没有复杂的代码,是使用编码/解码到base64的两个函数。它们是atob()和btoa()。到目前为止,最简单和最好的方法,没有必要担心如果你错过了任何字符转义。

乔治

最好使用JSON.parse(yourUnescapedJson);

使用encodeURIComponent()对字符串进行编码。

如。var myEscapedJSONString = encodeURIComponent(JSON.stringify(myJSON));

你不需要解码它,因为web服务器会自动做同样的事情。

编辑:检查你正在交互的api是否被设置为Content-Type: application/json, &/或者你的客户端http库是否在后台stringify和解析http请求体。我的客户端库是由swagger生成的,这也是我需要应用这些hacks的原因,因为客户端库正在对我的__abc4 - stringized body (body: “jsonString”,而不是body: { ...normal payload })进行字符串化。我所要做的就是将api更改为Content-Type: text/plain,这就删除了该路由上的JSON stringify/解析,然后这些hack都不需要了。你也可以只更改“消费”;或“;produces"部分,在这里看到的

如果你的google一直在这里登陆你,你的api抛出错误,除非你的JSON双引号转义("{\"foo\": true}"),所有你需要做的是stringify两次,例如JSON.stringify(JSON.stringify(bar))

RegExp单行,使用这个函数:

function escapeJSON(string) {
return string.replace(/[\n"\&\r\t\b\f]/g, '\\$&');
}