I'm trying to parse a JSON string obtained from an API:
var inputString = '{ "AccountName": "NT AUTHORITY\\SYSTEM"}'
console.log(JSON.parse(inputString)) // View in browser console to see real error
Above code gives error:
Uncaught SyntaxError: Unexpected token S in JSON at position 31
at JSON.parse ()
at program.html:7
Now below code works:
var inputString = '{ "AccountName": "NT AUTHORITY\\\\SYSTEM"}'
console.log(JSON.parse(inputString))
It shows the output:
{AccountName: "NT AUTHORITY\SYSTEM"}
Backslash character is an escape sequence in JSON. But why do I require four backslashes to create a single backslash? Shouldn't it be only \\?
The JSON response that I'm getting from the API being called is giving me only two \\ where ever there is a path. So my code is breaking. I believe API's JSON format is correct. When I try to parse this response on online JSON viewer then they are able to parse it successfully.
First, the template literal is parsed. Just like in ordinary strings, a double backslash is translated into a single literal backslash. So, your initial inputString:
var inputString = `{ "AccountName": "NT AUTHORITY\\SYSTEM"}`
will have a single backslash in it.
console.log(`\\`.length);
Unlike plain Javascript strings (in which unnecessary backslashes are just ignored), JSON format requires that backslashes precede a special character to be escaped (like a " or another \). If a backslash and the following character does not translate to an escape character, a SyntaxError like the one you see in your question will be thrown.
So, to indicate a literal backslash in a JSON, you need two backslashes in the JSON, and to indicate a literal backslash in a Javascript string, you also need two backslashes. Together, you need four backslashes in order to indicate a literal backslash in the JSON.
If you wish to manually write strings that include literal backslashes, and you don't need to use escape characters, you might consider using String.raw for your template literals, which parse single backslashes as literal backslashes rather than as part of an escape sequence:
console.log(
String.raw`\\`.length
);
const inputString = String.raw`{ "AccountName": "NT AUTHORITY\\SYSTEM"}`;
console.log(JSON.parse(inputString))
You've got string inside template string. One backslash is consumed by template string and the other is for quoted text
Related
With JSON.parse:
This works:
JSON.parse('{\"V\":\"\u008c\"}') // => { V: '' }
This doesn't:
JSON.parse('{\"V\":\"\u0000\"}') // >> SyntaxError: Unexpected token in JSON at position 6
What is the concept here?
You can find some information in the RFC 4627. For example:
2.5. Strings
The representation of strings is similar to conventions used in the C
family of programming languages. A string begins and ends with
quotation marks. All Unicode characters may be placed within the
quotation marks except for the characters that must be escaped:
quotation mark, reverse solidus, and the control characters (U+0000
through U+001F).
Now, related to your problem, you just need to escape the \ on your unicode character for the parsing to work:
JSON.parse('{"V":"\\u0000"}')
Result: {V: "�"}
And just for you information, no need to escape the " inside a single-quoted string in javascript.
The only issue is that you're expressing your JSON as a Javascript string literal. This is valid JSON:
{"V":"\u0000"}
This however is a Javascript string containing the value {"V":"<NUL>"}:
'{\"V\":\"\u0000\"}'
Javascript was already interpreting the \u0000 escape sequence and JSON.parse was consequently trying to parse a JSON string with a NUL byte in it, which is illegal (NUL must be escaped).
The actual Javascript string literal representation of the JSON you were attempting is:
JSON.parse('{"V":"\\u0000"}')
↑
This question already has answers here:
How do I handle newlines in JSON?
(10 answers)
Closed 7 years ago.
Why can't you parse a json with a \n character in javascript
JSON.parse('{"x": "\n"}')
However when you do JSON.parse(JSON.stringify({"x" : "\n"})), it is valid.
http://www.jslint.com/ says that {"x": "\n"} is a valid JSON. I wonder what does spec says about this?
Update:
For those who marked this duplicate, this is not the same question as "How to handle newlines in JSON". This question is more about why can't an unescaped newline character allowed in JSON.
JSON.parse('{"x": "\n"}') fails because '{"x": "\n"}' is not a valid JSON string due to the unescaped slash symbol.
JSON.parse() requires a valid JSON string to work.
'{"x": "\\n"}' is a valid JSON string as the slash is now escaped, so JSON.parse('{"x": "\\n"}') will work.
JSON.parse(JSON.stringify({"x" : "\n"})) works because JSON.stringify internally escapes the slash character.
The result of JSON.stringify({"x" : "\n"}) is {"x":"\n"} but if you try to parse this using JSON.parse('{"x":"\n"})' it will FAIL, as it is not escaped. As JSON.stringify returns an escaped character, JSON.parse(JSON.stringify()) will work.
It need to be:
JSON.parse('{"x": "\\n"}')
You must use \\ to escape the character.
Why it's invalid?
It' from rfc4627 specs
All Unicode characters may be placed within the quotation marks except for the characters that must be escaped: quotation mark, reverse solidus, and the control characters (U+0000 through U+001F)." Since a newline is a control character, it must be escaped.
In JavaScript "\n" is not the literal string \n. It is a string containing a newline character. That makes your JSON invalid.
To represent the literal string \n, you need to escape the initial backslash character with another backslash character: "\\n".
You need to escape the "\" in your string (turning it into a double-"\\"), otherwise it will become a newline in the JSON source, not the JSON data.
Try to replace \n with some other characters while parsing and again replace those characters with \n before assigning this value to some control.
When JSON string has \ at the end of any string it gives me:
Ext.JSON.decode(): You're trying to decode an invalid JSON String
JSON decode error:
Uncaught Ext.JSON.decode(): You're trying to decode an invalid JSON
String:
[{"ID1":"1","ID2":"1","NAME":"Act\"},{"ID1":"3","ID2":"1","NAME":"Act\"},{"ID1":"4","ID2":"2","NAME":"act $#%^&&*"},{"ID1":"2","ID2":"2","NAME":"act $#%^&&*"}]
How can i avoid above error?
That is invalid JSON, because the \ character escapes the " mark which would be responsible for closing the string - as such, your string remains unclosed (that is, until the next " comes around).
So your problem is that a backslash has a special meaning inside strings. If you want to use slashes, use \\ instead. (Note that what this does is escape the backslash character itself.)
ie.:
{"ID1":"1","ID2":"1","NAME":"Act\\"}
You need to escape that backslash. Initially I thought you would only need to use one escape character, but, according to this demonstration, you need to use three:
{"ID1":"1","ID2":"1","NAME":"Act\\\\"}
If you test your JSON, you will see that it's not valid : http://jsonlint.com/
You'll need to escape your \ with another \
\\Act
You should encode your JSON before, or make it manually if possible.
I want to generate the string "\" in Javascript but couldn't seem to do it. If I only write "\", I would get compile time error because " itself is escaped. But if I do "\\", I would get two slashes as the output. So how do I generate a string with a single forward slash?
The character / is a slash. The character \ is a backslash.
Backslash \ is used as an escape character for strings in JavaScript, and in JSON. It is required for some characters to remove ambiguity from string literals. This string is ambiguous:
'He's going to the park'
There are three single quote ' marks, and the parser doesn't know what is part of the string and what isn't. We can use a backslash to escape the one that we want to represent the character ' instead of the close of the string literal (also ').
'He\'s going to the park'
Now, if the backslash has special meaning, how do we represent a literal backslash \ character in the string? By simply escaping the backslash \ with a backslash \.
'C:\\DOS\\command.com' // In memory this is: C:\DOS\command.com
Remember that this escaping is only for the text representation of strings in code or JSON. The code is parsed and the strings in memory are what we would expect, with all escaping resolved to the proper characters.
Now your question asks about JSON and makes the assumption that this is incorrect:
I am writing '\' as the key to a JSON package. The result is something like "READY_TO_PRINT_DATE":"/\\Date(1403911292:981000+420)\\/".
JSON requires the same escaping as you find in JavaScript, and for the same reason... to remove ambiguity from strings. The JSON-version of the string /\\Date(1403911292:981000+420)\\/ is how you would properly represent the actual string /\Date(1403911292:981000+420)\/.
I hope this helps clears up some of your confusion.
you can escape the slash:
myvar = "\\";
I am of the understanding that if I am trying to stringify quotes (' and "), i need to escape them but I can't explain the following results when I tried the same out in firebug:
1. >> JSON.stringify({foo: "a"a'a"});
SyntaxError: missing } after property list
Inference: This is expected since I didn't escape " and '
2 >>> JSON.stringify({foo: "a\"a'a"});
"{"foo":"a\"a'a"}"
Inference/Question: Will the JSON string also show the escape character before " and why it works without escaping the single quote
Also JSON throws an error when I try to parse the output string generated above back to JS object ?
>>> JSON.parse("{"foo":"a\"a'a"}")
SyntaxError: missing ) after argument list
Finally Explain results below: Basically if I escape the single quote once, it doesn't show up in the output string but if I escape twice, it does
>>> JSON.stringify({foo: "a\"a\'a"});
"{"foo":"a\"a'a"}"
>>> JSON.stringify({foo: "a\"a\\'a"});
"{"foo":"a\"a\\'a"}"
Basically I am trying to understand when and how I need to escape single and double quotes when converting to and from JSON.
Thanks for your help
EDIT:
Thanks for the replies .
The first 2 queries are clear. So I only need to escape the quotes I am using to enclose the string ( in my case ") and escape any escape characters itself in the string. Other than these 2, I don't need to escape any other chars?
I am not clear on the last query. If I just increase the escape characters before ', why does it shows even number of escape chars in the output . For eg
>>> JSON.stringify({foo: "a\"a\'a"});
"{"foo":"a\"a'a"}"
>>> JSON.stringify({foo: "a\"a\\'a"});
"{"foo":"a\"a\\'a"}"
>>> JSON.stringify({foo: "a\"a\\\'a"});
"{"foo":"a\"a\\'a"}"
The format given by your JavaScript interpreter here is a little misleading when it outputs the following:
2 >>> JSON.stringify({foo: "a\"a'a"});
"{"foo":"a\"a'a"}"
The interpreter is adding the double quotes on the outside without doing any of the necessary escaping to make the result a valid string literal, so what this is actually trying to say is that the result of the expression is a string that contains {"foo":"a\"a'a"} (where every character there is literal, including the backslash). If you were going to write this as a JavaScript string literal it would be one of the following:
With double quotes: "{\"foo\":\"a\\\"a'a\"}"
With single quotes: '{"foo":"a\\"a\'a"}'
The above strings are exactly identical, they are just represented differently based on which external quote is used. You should be able to pass either of those strings to JSON.parse and get an object equivalent to what you started with.
Hopefully this will also help to clarify as to why the single quote isn't escaped, as shown above you only need to escape the type of quote that is used for the string literal (so escape internal double quotes if double quotes surround the string, and escape internal single quotes when single quotes are around the string).
So the errors being thrown is because the string is being ended. So any other characters that follow are attempted to be parsed but aren't able to be. Hence the errors.
So because you start with a quotation mark ("), using an apostrophe (') isn't ending the string. It's within the string, because your string is expected to end with another quotation mark.
If you want to include the same character that the string is defined within, it will need to be escaped. E.g. " and he said \"what a great day!\" to the other boy"
No need to escape single quotes inside of double quotes, or double quotes inside of single quotes.
You do need to escape like quotes within like quotes -- these are all valid syntax:
var a = "Testing '1234'";
var b = 'Testing "1234"';
var c = "Testing \"1234\"";
var d = 'Testing \'1234\'';
Second piece, on JSON stringification, the double quotes you see output here:
JSON.stringify({foo: "a\"a'a"});
"{"foo":"a\"a'a"}"
are just an output within whatever console or repl you are using. Technically those should be output as single quotes.
At any rate...
var s = JSON.stringify({foo: "a\"a'a"});
JSON.parse(s);
...will most definitely output a valid object.
Your first inference is correct; you need to escape any special characters (Quotation marks, in this case) that you want to appear in your final string. If you don't, then the browser will try to parse the string as-is, and will fail miserably because of mismatched quotes.
This is the same reason you get an error when you're parsing the string; the parser can't account for the mismatched quotes.
For the last behaviour you were having trouble with, you're not really escaping the quote twice; you're escaping the escape character.