JSON。解析无效的Json。逃脱了控制characters.If

时间:2021-01-03 20:16:52

I've escaped control characters and am feeding my validated JSON into JSON.parse and jQuery.parseJSON. Both are giving the same result.

我已经转义了控件字符,并将经过验证的JSON输入到JSON中。解析和jQuery.parseJSON。两者都给出了相同的结果。

Getting error message "Unexpected token $":

获取错误消息“意外令牌$”:

$(function(){
    try{
        $.parseJSON('"\\\\\"$\\\\\"#,##0"');
    } catch (exception) {
        alert(exception.message);
    }    
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>

Thanks for checking out this issue.

谢谢你检查这个问题。

2 个解决方案

#1


3  

In your original problem, why do you need to do JSONparse in the first place? You could have easily gotten the object you wanted by just doing

在最初的问题中,为什么需要首先执行JSONparse呢?你可以很容易地得到你想要的东西

var o = { blah }

by manually removing the single quotes you have around the curly braces rather than doing

手动删除你在花括号周围的单引号,而不是做。

$.JSONparse('{blah}')

Is there any reason for evaluating the string first (ie var s = '{blah}' and then doing $.JSONparse(s)) which is what your original code was doing? There shouldn't be a case where this is necessary. Since you mentioned somewhere that the string was produced by JSON.stringify, there shouldn't be a scenario where you need to explicitly store it into a variable (ie copy and paste it and put quotes around it).

是否有理由首先计算字符串(即var s = '{blah}',然后执行$.JSONparse(s))这就是原始代码所做的?不应该有这样的情况。因为您提到过,字符串是JSON生成的。stringify,不应该有一个场景,你需要显式地将它存储到一个变量中(复制粘贴它,并在它周围加上引号)。

The main problem here is the string produced by JSON.stringify, which is properly escaped, has been 'evaluated' once when you manually put braces around it. So the key is to make sure the string doesn't get 'evaluated'

这里的主要问题是JSON生成的字符串。stringify是正确转义的,当您手工在它周围放置大括号时,它会被“评估”一次。关键是要确保字符串不会被赋值

Even if you wanted to pass the stringified variable to database or anything, there is no need to explicitly use quotes. One could do

即使您想要将stringified变量传递到数据库或任何东西,也不需要显式地使用引号。一个可以做

var s = JSON.stringify(obj);
db.save("myobj",s)
var newObj = JSON.parse(db.load("myobj"))

The string is stored verbatim without getting evaluated, so that when you retrieve it, you would have the exact same string.

字符串是按原样存储的,不会被计算,所以当您检索它时,您将得到相同的字符串。

#2


5  

What's happening here is that there are two levels of backslash removal being applied to the string. The first is done by the browser's JavaScript engine when it parses the single-quoted string. In JavaScript, single-quoted strings and double-quoted strings are exactly equivalent (other than the fact that single-quotes must be backslash-escaped in single-quoted strings and double-quotes must be backslash-escaped in double-quoted strings); both types of strings take backslash escape codes such as \\ for backslash, \' for single-quote (redundant but accepted in double-quoted strings), and \" for double-quote (redundant but accepted in single-quoted strings).

这里发生的是有两个级别的反斜杠删除被应用到字符串中。第一个由浏览器的JavaScript引擎在解析单引号字符串时完成。在JavaScript中,单引号字符串和双引号字符串是完全等价的(除了单引号必须在单引号字符串中反斜线转义,双引号必须在双引号字符串中反斜线转义);这两种字符串都有反斜杠转义码,如\ for backslash, \' for single-quote(冗余但双引号中接受),\“for double-quote(冗余但在单引号中接受)”。

In your JavaScript single-quoted string literal you have several instances of this kind of thing, which are meant to be valid JSON double-quoted strings:

在JavaScript单引号字符串文字中,有几个这样的实例,它们是有效的JSON双引号字符串:

"\\\\\"$\\\\\"#,##0"

After the browser has parsed it, the string contains exactly the following characters (including the outer double-quotes, which are unremoved because they are contained in a single-quoted string):

浏览器解析后,该字符串包含以下字符(包括外部双引号,由于它们包含在单引号字符串中,所以未被删除):

"\\"$\\"#,##0"

You can see that each consecutive pair of backslashes became a single literal backslash, and the two cases of an odd backslash followed by a double-quote each became a literal double-quote.

您可以看到,每一对连续的反斜杠都变成了单个的字面反斜杠,奇数反斜杠后面跟着双引号的两种情况都变成了字面的双引号。

That is the text that is being passed as an argument to $.parseJSON, which is when the second level of backslash removal occurs. During JSON parsing of the above text, the leading double-quote signifies the start of a JSON string literal, then the pair of backslashes is interpreted as a single literal backslash, and then the immediately following double-quote terminates the JSON string literal. The stuff that follows (dollar, backslash, backslash, etc.) is invalid JSON syntax.

这是作为参数传递给$的文本。parseJSON,当发生第二级反斜杠删除时。在上述文本的JSON解析过程中,前面的双引号表示JSON字符串字面量的开始,然后将两个反斜杠解释为单个文本反斜杠,然后紧接着的双引号终止了JSON字符串的文字。后面的内容(元、反斜杠、反斜杠等)是无效的JSON语法。

The problem is that you've embedded valid JSON in a JavaScript single-quoted string literal, which, although it happens to be valid JavaScript syntax by fluke (it wouldn't have been if the JSON contained single-quotes, or if you'd tried using double-quotes to delimit the JavaScript string literal), no longer contains valid JSON after being parsed by the browser's JavaScript engine.

问题是,你在一个JavaScript嵌入有效的JSON使用单引号字符串文字,,尽管它是有效的JavaScript语法由侥幸(它不会如果JSON包含单引号,或如果你试着用双引号分隔的JavaScript字符串),不再包含有效的JSON解析后浏览器的JavaScript引擎。

To solve the problem, you have to either manually escape the JSON content to be properly embedded in a JavaScript string literal, or load it independently of the JavaScript source, e.g. from a flat file.

要解决这个问题,您必须手动转义JSON内容,以便正确地嵌入到JavaScript字符串文字中,或者独立于JavaScript源(例如,从平面文件中)加载它。

Here's a demonstration of how to solve the problem using your latest example code:

下面演示如何使用最新的示例代码解决这个问题:

$(function() {
    try {
        alert($.parseJSON('{"key":"\\\\\\\\\\"$\\\\\\\\\\"#,##0"}').key); // works
        alert($.parseJSON('{"key":"\\\\\"$\\\\\"#,##0"}').key); // doesn't work
    } catch (exception) {
        alert(exception.message);
    }    
});

http://jsfiddle.net/814uw638/2/

http://jsfiddle.net/814uw638/2/

Since JavaScript has a simple escaping scheme (e.g. see http://blogs.learnnowonline.com/2012/07/19/escape-sequences-in-string-literals-using-javascript/), it's actually pretty easy to solve this problem in the general case. You just have to decide in advance how you're going to quote the string in JavaScript (single-quotes are a good idea, because strings in JSON are always double-quoted), and then when you prepare the JavaScript source, just add a backslash before every single-quote and every backslash in the embedded JSON. That should guarantee it will be perfectly valid, regardless of the exact JSON content (provided, of course, that it is valid JSON to begin with).

由于JavaScript有一个简单的转义方案(如http://blogs.learnnowonline.com/2012/07/19/escape- sequencencencencations -literals-using-javascript/),在一般情况下解决这个问题其实很容易。您只需要预先决定如何引用JavaScript中的字符串(单引号是个好主意,因为JSON中的字符串总是被重复引用),然后在准备JavaScript源代码时,在每个单引号和嵌入式JSON中的每个反斜杠之前添加一个反斜杠。这应该保证它是完全有效的,无论JSON内容是什么(当然,前提是它是有效的JSON)。

#1


3  

In your original problem, why do you need to do JSONparse in the first place? You could have easily gotten the object you wanted by just doing

在最初的问题中,为什么需要首先执行JSONparse呢?你可以很容易地得到你想要的东西

var o = { blah }

by manually removing the single quotes you have around the curly braces rather than doing

手动删除你在花括号周围的单引号,而不是做。

$.JSONparse('{blah}')

Is there any reason for evaluating the string first (ie var s = '{blah}' and then doing $.JSONparse(s)) which is what your original code was doing? There shouldn't be a case where this is necessary. Since you mentioned somewhere that the string was produced by JSON.stringify, there shouldn't be a scenario where you need to explicitly store it into a variable (ie copy and paste it and put quotes around it).

是否有理由首先计算字符串(即var s = '{blah}',然后执行$.JSONparse(s))这就是原始代码所做的?不应该有这样的情况。因为您提到过,字符串是JSON生成的。stringify,不应该有一个场景,你需要显式地将它存储到一个变量中(复制粘贴它,并在它周围加上引号)。

The main problem here is the string produced by JSON.stringify, which is properly escaped, has been 'evaluated' once when you manually put braces around it. So the key is to make sure the string doesn't get 'evaluated'

这里的主要问题是JSON生成的字符串。stringify是正确转义的,当您手工在它周围放置大括号时,它会被“评估”一次。关键是要确保字符串不会被赋值

Even if you wanted to pass the stringified variable to database or anything, there is no need to explicitly use quotes. One could do

即使您想要将stringified变量传递到数据库或任何东西,也不需要显式地使用引号。一个可以做

var s = JSON.stringify(obj);
db.save("myobj",s)
var newObj = JSON.parse(db.load("myobj"))

The string is stored verbatim without getting evaluated, so that when you retrieve it, you would have the exact same string.

字符串是按原样存储的,不会被计算,所以当您检索它时,您将得到相同的字符串。

#2


5  

What's happening here is that there are two levels of backslash removal being applied to the string. The first is done by the browser's JavaScript engine when it parses the single-quoted string. In JavaScript, single-quoted strings and double-quoted strings are exactly equivalent (other than the fact that single-quotes must be backslash-escaped in single-quoted strings and double-quotes must be backslash-escaped in double-quoted strings); both types of strings take backslash escape codes such as \\ for backslash, \' for single-quote (redundant but accepted in double-quoted strings), and \" for double-quote (redundant but accepted in single-quoted strings).

这里发生的是有两个级别的反斜杠删除被应用到字符串中。第一个由浏览器的JavaScript引擎在解析单引号字符串时完成。在JavaScript中,单引号字符串和双引号字符串是完全等价的(除了单引号必须在单引号字符串中反斜线转义,双引号必须在双引号字符串中反斜线转义);这两种字符串都有反斜杠转义码,如\ for backslash, \' for single-quote(冗余但双引号中接受),\“for double-quote(冗余但在单引号中接受)”。

In your JavaScript single-quoted string literal you have several instances of this kind of thing, which are meant to be valid JSON double-quoted strings:

在JavaScript单引号字符串文字中,有几个这样的实例,它们是有效的JSON双引号字符串:

"\\\\\"$\\\\\"#,##0"

After the browser has parsed it, the string contains exactly the following characters (including the outer double-quotes, which are unremoved because they are contained in a single-quoted string):

浏览器解析后,该字符串包含以下字符(包括外部双引号,由于它们包含在单引号字符串中,所以未被删除):

"\\"$\\"#,##0"

You can see that each consecutive pair of backslashes became a single literal backslash, and the two cases of an odd backslash followed by a double-quote each became a literal double-quote.

您可以看到,每一对连续的反斜杠都变成了单个的字面反斜杠,奇数反斜杠后面跟着双引号的两种情况都变成了字面的双引号。

That is the text that is being passed as an argument to $.parseJSON, which is when the second level of backslash removal occurs. During JSON parsing of the above text, the leading double-quote signifies the start of a JSON string literal, then the pair of backslashes is interpreted as a single literal backslash, and then the immediately following double-quote terminates the JSON string literal. The stuff that follows (dollar, backslash, backslash, etc.) is invalid JSON syntax.

这是作为参数传递给$的文本。parseJSON,当发生第二级反斜杠删除时。在上述文本的JSON解析过程中,前面的双引号表示JSON字符串字面量的开始,然后将两个反斜杠解释为单个文本反斜杠,然后紧接着的双引号终止了JSON字符串的文字。后面的内容(元、反斜杠、反斜杠等)是无效的JSON语法。

The problem is that you've embedded valid JSON in a JavaScript single-quoted string literal, which, although it happens to be valid JavaScript syntax by fluke (it wouldn't have been if the JSON contained single-quotes, or if you'd tried using double-quotes to delimit the JavaScript string literal), no longer contains valid JSON after being parsed by the browser's JavaScript engine.

问题是,你在一个JavaScript嵌入有效的JSON使用单引号字符串文字,,尽管它是有效的JavaScript语法由侥幸(它不会如果JSON包含单引号,或如果你试着用双引号分隔的JavaScript字符串),不再包含有效的JSON解析后浏览器的JavaScript引擎。

To solve the problem, you have to either manually escape the JSON content to be properly embedded in a JavaScript string literal, or load it independently of the JavaScript source, e.g. from a flat file.

要解决这个问题,您必须手动转义JSON内容,以便正确地嵌入到JavaScript字符串文字中,或者独立于JavaScript源(例如,从平面文件中)加载它。

Here's a demonstration of how to solve the problem using your latest example code:

下面演示如何使用最新的示例代码解决这个问题:

$(function() {
    try {
        alert($.parseJSON('{"key":"\\\\\\\\\\"$\\\\\\\\\\"#,##0"}').key); // works
        alert($.parseJSON('{"key":"\\\\\"$\\\\\"#,##0"}').key); // doesn't work
    } catch (exception) {
        alert(exception.message);
    }    
});

http://jsfiddle.net/814uw638/2/

http://jsfiddle.net/814uw638/2/

Since JavaScript has a simple escaping scheme (e.g. see http://blogs.learnnowonline.com/2012/07/19/escape-sequences-in-string-literals-using-javascript/), it's actually pretty easy to solve this problem in the general case. You just have to decide in advance how you're going to quote the string in JavaScript (single-quotes are a good idea, because strings in JSON are always double-quoted), and then when you prepare the JavaScript source, just add a backslash before every single-quote and every backslash in the embedded JSON. That should guarantee it will be perfectly valid, regardless of the exact JSON content (provided, of course, that it is valid JSON to begin with).

由于JavaScript有一个简单的转义方案(如http://blogs.learnnowonline.com/2012/07/19/escape- sequencencencencations -literals-using-javascript/),在一般情况下解决这个问题其实很容易。您只需要预先决定如何引用JavaScript中的字符串(单引号是个好主意,因为JSON中的字符串总是被重复引用),然后在准备JavaScript源代码时,在每个单引号和嵌入式JSON中的每个反斜杠之前添加一个反斜杠。这应该保证它是完全有效的,无论JSON内容是什么(当然,前提是它是有效的JSON)。