views:

122

answers:

3

Since the JSON format specifies that single quotes should not be escaped, most libraries (or even the native JSON parser) will fail if you have an escaped single quote in it. Now this usually is not a problem since most of the time you do an XHR that fetches some data formatted as JSON and you use the responseText which contains your JSON string that you can then parse, etc.

In this particular situation, I have a JSON string stored in a database as text... so the database contains something like {"property":"value"} and I want to output this as part of an HTML page created by the server so that the JavaScript code in that page looks something like this:

var x = '{"property":"value"}';

Now if the JSON string in the database contains a single quote like this:

{"property":"val'ue"}

Then I need to escape it or else I will never be able to use it as a string:

console.clear();
var obj = {prop:"val'ue"};
var str = JSON.stringify(obj);
console.log("JSON string is %s",str);
console.dir(JSON.parse(str)); //No problem here


//This obviously can't work since the string is closed and it causes an invalid script
//console.dir(JSON.parse('{prop:"val'ue"}'));

//so I need to escape it to use a literal JSON string
console.dir(JSON.parse('{"prop":"val\'ue"}'));

The question then is why {"prop":"val\'ue"} not considered a valid JSON string ?

+2  A: 

According to jsonlint it is valid without escaping the single quote, so this is fine:

{"prop": "val'ue"}

But this is invalid:

{"prop":"val\'ue"}

According to json.org json:

is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others

So it is the language conventions in c-type languages regarding the reverse solidus (\) that means that your example is not valid.

amelvin
+1 this definitely answers the "Why is `\'` not valid in JSON strings" part of the question
gnarf
+1  A: 

You might try the following, however, it's ugly.

JSON.parse("{\"obj\":\"val'ue\"}");

Or just store the string to a var first. This should not store the literal backslash value and therefore the JSON parser should work.


var str =  '{"obj" : "val\'ue"}';
JSON.parse(str);

Jesse Brown
+2  A: 

In JavaScript - the string '{"prop":"val\'ue"}' is a correct way to encode the JSON as a string literal.

As the JavaScript interpreter reads the single-quoted string, it will convert the \' to '. The value of the string is {"prop":"val'ue"} which is valid JSON.

In order to create the invalid JSON string, you would have to write '{"prop":"val\\\'ue"}'

If I understand the question right, you are trying to generate JavaScript code that will set some variable to the decoded version of a JSON string you have stored in the database. So now you are encoding the string again, as the way to get this string into JavaScript is to use a string literal, passing it through JSON.parse(). You can probably rely on using the server side JSON encoder to encode the JSON string as a JavaScript string literal. For instance:

<?php $jsonString = '{"prop":"val\'ue"}'; ?>
var myJson = JSON.parse(<?php echo json_encode($jsonString) ?>);
// Prints out: 
// var myJson = JSON.parse("{\"prop\":\"val'ue\"}");
// And results: Object - { prop: "val'ue"}

However, If you are 100% sure the JSON is going to be valid, and don't need the weight of the extra parsing / error checking - you could skip all that extra encoding and just write:

var myJson = <?php echo $jsonString; ?>

Remember, JSON is valid JavaScript syntax for defining objects after all!

gnarf
Thx, I definitely got into the wrong thinking, best is definitely to re-encode it as you say, this way the javaScript interpreter will store the 'interpreted' string value, causing the VALUE of the variable to be a valid JSON string.
SBUJOLD
@SBUJOLD - no problem :) glad I could steer you back to the right path!
gnarf
+1 Good explanation.
amelvin