Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON.parse failing on valid Json. Have escaped control characters.If

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

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.

like image 880
robbintt Avatar asked Jan 18 '15 10:01

robbintt


People also ask

What happens if JSON parse fails?

If passed an invalid JSON value, the method will throw an error, which will get passed to the catch() function. You can handle the error in the catch function as you see fit. If you use local storage to get the value you're parsing, open your browser's console and clear the local storage as it sometimes glitches.

What error does JSON parse () throw when the string to parse is not valid JSON?

Exceptions. Throws a SyntaxError exception if the string to parse is not valid JSON.

What characters should be escaped in JSON?

In JSON the only characters you must escape are \, ", and control codes. Thus in order to escape your structure, you'll need a JSON specific function.


1 Answers

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

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:

"\\\\\"$\\\\\"#,##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.

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.

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.

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/

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

like image 120
bgoldst Avatar answered Oct 10 '22 00:10

bgoldst