Parsing string as JSON with single quotes on key and keyvalue [duplicate] - javascript

This question already has answers here:
Parsing string as JSON with single quotes?
(10 answers)
Closed 1 year ago.
var str = "{'a':'Your's'}";
JSON.parse(str);
My server response like above string. Not able to parse as JSON. It is as example text. While am parsing I got error as below:
JSON.parse(str);
VM1951:1 Uncaught SyntaxError: Unexpected token ' in JSON at position 1(…)(anonymous function) # VM1950:1
The same question already raised by someone. click here to see. But, not helpful. Please help on this. Thanks in advance.

TL;DR JSON only supports double quotes.
Please fix the error on the server, if this is possible.
JSON required double quotes, the single quotes are therefore not conform to the standard. There may be parsers, that support them anyway, but you can never rely on that. For more details on the JSON syntax, you may have a look at http://www.json.org/.
Besides this, the input string "{'a':'Your's'}"; is totally invalid itself, if the single quotes would be valid. The ' in Your's is breaking the string literal, the following s is outside the string and the next ' is opening a string, that contains } but is never closed by another '.
The correct syntax would be '{"a":"Your\'s"}'.
If you received the string and cannot correct the server output, you may try to replace all ' by ", but you will have problems with single quotes inside your payload strings. By far the easiest - and most stable(!) - fix should be correcting the server output instead of correcting the defect output on the client.
Converting on the client with the following code may be a good idea at the first thought, but would corrupt payload strings with single quotes in it.
replaceInString = function(fullString, search, replacement) {
return fullString.split(search).join(replacement);
};
var json = replaceInString("{'a':'Your's'}", "'", '"');
If you can be sure, there are no whitespace characters outside the payload and also there are no line breaks, you could use the following function. But also only, if you are sure, the search patterns are not in the payload strings.
var json = "{'a':'Your's'}";
replaceInString = function(fullString, search, replacement) {
return fullString.split(search).join(replacement);
};
json = replaceInString(json, "{'", '{"');
json = replaceInString(json, "'}", '"}');
json = replaceInString(json, "':", '":');
json = replaceInString(json, ":'", ':"');
json = replaceInString(json, "',", '",');
json = replaceInString(json, ",'", ',"');
json = replaceInString(json, "['", '["');
json = replaceInString(json, "']", '"]');
But using this code, e.g. the JSON `following JSON string would be corrupted.
{'mathTerm':'x=1-[2+A']'}
To be clear: Code like this gets you over a bump on the road to develop , test or learn something. But this is not a durable fix. Contact the server developer to fix his implementation and remove your client side fix before going to production.

JSON keys and values must be enclosed in double quotes (") instead of single quotes (')
This is correct:
var str = '{"a":"Your\'s"}';
JSON.parse(str);

Related

Using Javascript, how can I parse a JSON string containing a JSON string?

I'm reading data using Javascript fetch from an Azure Table Storage, where one of the columns contain a JSON string. So I'm getting back a string that I don't know how to format so that I can parse it.
let jsonData =
'{"Timestamp":"2019-10-01T14:19:48.2593745+00:00","Data":"{\"app_id\":\"apple\",\"dev_id\":\"node1\",\"hardware_serial\":\"001122334455667788\",\"port\":1,\"counter\":63,\"payload_raw\":\"afIWk0ccABwM1Ag=\",\"payload_fields\":{\"doorState\":\"open\",\"humidity\":31,\"location\":{\"lat\":0,\"lon\":0},\"temperature\":22.6},\"metadata\":{\"time\":\"2019-10-01T14:19:48.009374928Z\",\"frequency\":867.9,\"modulation\":\"LORA\",\"data_rate\":\"SF7BW125\",\"coding_rate\":\"4/5\",\"gateways\":[{\"gtw_id\":\"banana\",\"gtw_trusted\":true,\"timestamp\":3579682692,\"time\":\"2019-10-01T14:19:47Z\",\"channel\":7,\"rssi\":-118,\"snr\":-5,\"rf_chain\":0,\"latitude\":0,\"longitude\":0,\"altitude\":172,\"location_source\":\"registry\"},{\"gtw_id\":\"banana\",\"timestamp\":567219172,\"time\":\"2019-10-01T14:19:47.98531Z\",\"channel\":7,\"rssi\":-55,\"snr\":10,\"rf_chain\":0,\"latitude\":0,\"longitude\":0,\"location_source\":\"registry\"}]},\"downlink_url\":\"https://www.someurl.com\"}"}';
After some testing I see that the escape backslashes cause problems, in addition to the quotation marks around the inner JSON object.
In short, parsing this fails:
let jsonData2 = '{"Test":"21342345","Data":"{\"test\":\"ethneipnrt\"}"}';
But this works:
let jsonData2 = '{"Test":"21342345","Data":{"test":"ethneipnrt"}}';
But how can I format the string automatically so that parsing works?
I got the parsing to work yesterday by filtering away the unwanted elements. First replacing all instances of '"{' with '{', then replacing all instances of '}"' with '}', and finally removing all backslashes.
let data = jsonData.replace(/"{/g, '{').replace(/}"/g, '}').replace(/\\/g, '');
let parsed = JSON.parse(data);
I agree that this should probably be handled in the backend. But for now it's enough to get the page up and running.

Why does json.parse break? and how to fix it

I have the following data coming in from my server into my js code, from my server.
{"triggers": [{"message_type": "sms","recipients": "[\"+91xxxxxxxxx\",\"+91xxxxxxxxx\"]","message": "This is a test"}]}
My code parses the above json string in the following manner.
data = '{"triggers": [{"message_type": "sms","recipients": "[\"+91xxxxxxxx\",\"+91xxxxxxxx\"]","message": "This is a test"}]}'
parsed = JSON.parse(data);
This throws the following exception
Uncaught SyntaxError: Unexpected token + in JSON at position 54
at JSON.parse (<anonymous>)
at eval (eval at <anonymous> (entry.html:2), <anonymous>:1:6)
at entry.html:298
I did a little bit of further digging and found the source of the json string.
Here is where the string is coming in from my python code
data = {"recipients": "[\"+91xxxxxxxxx\",\"+91xxxxxxxx\"]"} # This data comes in from my database, and I can't do anything about what quotes are used.
javascript_supplied_data = json.dumps(data) #This data goes to the frontend via webhook
I tried putting the same data into a json view via this online viewer, and it didn't throw any error and displayed the data correctly.
What I can't understand is, I am doing a json.dumps in my python code, so the string response should be json parsable. So why does JSON.parse throw this error?
Is there something wrong with the json libraries at the python end or the javascript end, or am I too much of a noob?.
Please help me figure out what is causing this issue, and how to solve it.
NOTE: I don't have any control over the string that comes in from the server.
When you have valid JSON, but put it in a string literal, the escapes treated by the literal notation in JavaScript make the string different. The backslashes are interpreted as for escaping the next character.
So either you have to go through the string literal and double all the backslashes, or you can apply String.raw to the string literal as template string:
var data = String.raw`{"triggers": [{"message_type": "sms","recipients": "[\"+91xxxxxxxx\",\"+91xxxxxxxx\"]","message": "This is a test"}]}`;
var parsed = JSON.parse(data);
console.log(parsed);
Note however, that the JSON you posted at the start of your question is valid.
On the other hand, the error you get indicates that the \" just before the first + is interpreted as just ". This means the \ is not actually there when the string is received from the server. This is usually caused by a similar escaping problem at the server side, where the programmer intended to send the backslash to the client, but actually just escaped the " on the server, which resulted in only the " being sent to the client and not \".
You have to use single quotes here while escape sequence.
if we use double quotes for escape sequence here it will result in
"recipients": "["+91xxxxxxxx","+91xxxxxxxx"]"
double quotes inside double quotes which is why your code breaks.
data = '{"triggers": [{"message_type": "sms","recipients": "[\'+91xxxxxxxx\',\'+91xxxxxxxx\']","message": "This is a test"}]}';
parsed = JSON.parse(data);
console.log(parsed)

jQuery and JSON issue

I'm having an issue with the parser of jQuery when I give him a JSON string like this (java):
String JSONvalue = "[{"evaluationId":92688,"ResponseId":378501,"comment":"I can't do this ~!##$%^&*()_+|}{\":?><\/.,;'[]\\=-0987654321`","rankingId":0}]";
and when I pass it to the parser (javascript), it looks like this:
var prevCommentsAndRankings = jQuery.parseJSON('[{"evaluationId":92688,"ResponseId":378501,"comment":"I can't do this ~!##$%^&*()_+|}{\":?><\/.,;'[]\\=-0987654321`","rankingId":0}]');
I'm getting error of invalid tokens, this is because of the ' " and [ ] on the JSON string. How could I handle them, consider that the JSON may always have special characters within. Thanks in advance !
Just for the arbitrary strings replace the quote with it's HTML entity " BEFORE rendering it in JSON and right after you parsed the JSON. Both are common function you can find in Java and Javascript.

How to use a JSON literal string?

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 ?
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!
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.
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);

javascript eval json with base64 encoded field

I am using sun.misc.BASE64Encoder to encode an encrypted value, which is then added to a JSON field and subsequently sent to the client. I use Javascript's eval() function on the client to create an object from the JSON code. When eval() runs, it gives the error:
unterminated string literal
There are other fields in the JSON code, but I've narrowed the error specifically to the base64 encoded field. Here's the offending line of javascript code:
var result = eval( '(' + xhr.responseText + ')' );
Here's the JSON object from the Servlet:
{
'resource':'resource?Signature=j79r/2Hly+HqhS/6fdd+prfsR+kUNijUvDN0QJ14ZR43gzYScOMDypt/crks/CEphTUXVptJvSol
1ZOOvScCUhNOCb7dZk/3MKnI5tOewSACXK32/OJNd8hYpZtSTn+WhA6+f9BUIUZWA83U8Cud/Tb8V
R1yQWbDGG/mM/NiUSiY=',
'url':'http://somesite.com/pr'
}
I'm not sure why eval is dying, but it seems the value of the 'resource' JSON field contains something it doesn't care for.
Thanks in advance.
Tim
I think it may be because your JSON appears to have line breaks in it. If you remove them, does it work?

Categories