jQuery。由于转义了JSON中的单引号,parseJSON抛出“无效JSON”错误

我使用jQuery.post()向服务器发出请求,服务器返回JSON对象(如{ "var": "value", ... })。但是,如果任何值包含单引号(像\'那样正确转义),jQuery将无法解析其他有效的JSON字符串。下面是我的意思的一个例子(在Chrome的控制台上完成):

data = "{ \"status\": \"success\", \"newHtml\": \"Hello \\\'x\" }";
eval("x = " + data); // { newHtml: "Hello 'x", status: "success" }


$.parseJSON(data); // Invalid JSON: { "status": "success", "newHtml": "Hello \'x" }

这正常吗?是否没有办法通过JSON正确地传递单引号?

181059 次浏览

根据JSON的网站上的状态机图,只允许转义的双引号字符,不允许单引号。单引号字符不需要转义:

http://www.json.org/string.gif

< p >
Update -感兴趣的人可以获得更多信息:


Douglas Crockford没有具体说明为什么JSON规范不允许在字符串中转义单引号。然而,在他在JavaScript的附录E:好的部分中讨论JSON时,他写道:

JSON的设计目标是最小化、可移植、文本化,并且是JavaScript的子集。为了实现互操作,我们需要的共识越少,我们就越容易实现互操作。

因此,也许他决定只允许使用双引号定义字符串,因为这减少了所有JSON实现必须同意的规则。因此,字符串中的单引号字符不可能意外地终止字符串,因为根据定义,字符串只能由双引号字符结束。因此,在正式规范中不需要允许转义单引号字符。

人力资源/ > < p > < 再深入挖掘一下,Crockford的JSON for Java的org.json实现是更允许的,允许单引号字符:

toString方法生成的文本严格遵守JSON语法规则。构造函数在它们将接受的文本中更加宽容:

...

  • 字符串可以用'(单引号)引用。

这是由JSONTokener源代码确认的。nextString方法接受转义单引号字符,并像对待双引号字符一样对待它们:

public String nextString(char quote) throws JSONException {
char c;
StringBuffer sb = new StringBuffer();
for (;;) {
c = next();
switch (c) {


...


case '\\':
c = this.next();
switch (c) {


...


case '"':
case '\'':
case '\\':
case '/':
sb.append(c);
break;
...

方法的顶部是一条信息丰富的注释:

正式的JSON格式不允许字符串加单引号,但允许实现接受它们。

因此,一些实现将接受单引号-但您不应该依赖于此。许多流行的实现在这方面有很大的限制,将拒绝包含单引号字符串和/或转义单引号的JSON。


最后,回到最初的问题,jQuery.parseJSON首先尝试使用浏览器的原生JSON解析器或加载的库,如json2.js(另一方面,如果没有定义JSON,则是jQuery逻辑所基于的库)。因此,jQuery只能像底层实现一样允许:

parseJSON: function( data ) {
...


// Attempt to parse using the native JSON parser first
if ( window.JSON && window.JSON.parse ) {
return window.JSON.parse( data );
}


...


jQuery.error( "Invalid JSON: " + data );
},

据我所知,这些实现只遵循官方JSON规范,不接受单引号,因此jQuery也不接受。

有趣。如何在服务器端生成JSON ?您是使用库函数(如PHP中的json_encode),还是手动构建JSON字符串?

唯一吸引我注意的是转义撇号(\')。鉴于您使用的是双引号,实际上应该使用双引号,因此没有必要转义单引号。我不能检查这是否是你的jQuery错误的原因,因为我自己还没有更新到1.4.1版本。

如果需要在字符串中使用单引号,由于\'在规范中未定义,请使用\u0027参见http://www.utf8-chartable.de/

编辑:请原谅我在评论中误用了“倒勾”这个词。我说的是反斜杠。我在这里的观点是,如果你在其他字符串中嵌套了字符串,我认为使用unicode而不是大量的反斜杠来转义一个单引号会更有用和可读。如果你没有嵌套,但它真的是更容易只是把一个普通的旧报价在那里。

当您在查询中发送单引号时

empid = " T'via"
empid =escape(empid)

当您获得包含单引号的值时

var xxx  = request.QueryString("empid")
xxx= unscape(xxx)

如果你想在查询中搜索/插入包含单引号的值 xxx=Replace(empid,"'","''") < / p >

我知道问题在哪里,当我查看规范时,很明显,未转义的单引号应该被正确解析。

我正在使用jquery的jquery。parseJSON函数来解析JSON字符串,但是当使用json_encode准备的数据中有一个单引号时,仍然会得到解析错误。

这可能是一个错误,在我的实现看起来像这样(PHP -服务器端):

$data = array();


$elem = array();
$elem['name'] = 'Erik';
$elem['position'] = 'PHP Programmer';
$data[] = json_encode($elem);


$elem = array();
$elem['name'] = 'Carl';
$elem['position'] = 'C Programmer';
$data[] = json_encode($elem);


$jsonString = "[" . implode(", ", $data) . "]";

最后一步是我将JSON编码的字符串存储到一个JS变量中:

<script type="text/javascript">
employees = jQuery.parseJSON('<?=$marker; ?>');
</script>

如果我使用“”而不是“,它仍然抛出一个错误。

解决方案:

唯一对我有用的是使用位掩码JSON_HEX_APOS来转换单引号,就像这样:

json_encode($tmp, JSON_HEX_APOS);

有没有别的办法解决这个问题?我的代码是错误的还是写得很糟糕?

谢谢

使用CakePHP输出一个JavaScript脚本块,使用PHP的原生json_encode,也遇到了类似的问题。$contractorCompanies包含有单引号的值,如上所述,json_encode($contractorCompanies)不会转义它们,因为它是有效的JSON。

<?php $this->Html->scriptBlock("var contractorCompanies = jQuery.parseJSON( '".(json_encode($contractorCompanies)."' );"); ?>

通过在JSON编码的字符串周围添加addslashes(),然后转义引号,允许Cake / PHP将正确的javascript回显到浏览器。JS错误消失。

<?php $this->Html->scriptBlock("var contractorCompanies = jQuery.parseJSON( '".addslashes(json_encode($contractorCompanies))."' );"); ?>

我试图将一个JSON对象从XHR请求保存到HTML5 data-*属性。我尝试了上面的许多方法,都没有成功。

我最终所做的是在stringify()方法调用后使用正则表达式将单引号'替换为它的代码&#39;,方法如下:

var productToString = JSON.stringify(productObject);
var quoteReplaced = productToString.replace(/'/g, "&#39;");
var anchor = '<a data-product=\'' + quoteReplaced + '\' href=\'#\'>' + productObject.name + '</a>';
// Here you can use the "anchor" variable to update your DOM element.