I’m making requests to my server using jQuery.post()
and my server is returning JSON objects (like { "var": "value", ... }
). However, if any of the values contains a single quote (properly escaped like \'
), jQuery fails to parse an otherwise valid JSON string. Here’s an example of what I mean (done in Chrome’s console):
data = "{ \"status\": \"success\", \"newHtml\": \"Hello \\\'x\" }";
eval("x = " + data); // { newHtml: "Hello 'x", status: "success" }
$.parseJSON(data); // Invalid JSON: { "status": "success", "newHtml": "Hello \'x" }
Is this normal? Is there no way to properly pass a single quote via JSON?
If you need a single quote inside of a string, since \' is undefined by the spec, use
\u0027
see http://www.utf8-chartable.de/ for all of themedit: please excuse my misuse of the word backticks in the comments. I meant backslash. My point here is that in the event you have nested strings inside other strings, I think it can be more useful and readable to use unicode instead of lots of backslashes to escape a single quote. If you are not nested however it truly is easier to just put a plain old quote in there.
Interesting. How are you generating your JSON on the server end? Are you using a library function (such as
json_encode
in PHP), or are you building the JSON string by hand?The only thing that grabs my attention is the escape apostrophe (
\'
). Seeing as you're using double quotes, as you indeed should, there is no need to escape single quotes. I can't check if that is indeed the cause for your jQuery error, as I haven't updated to version 1.4.1 myself yet.I was trying to save a JSON object from a XHR request into a HTML5 data-* attribute. I tried many of above solutions with no success.
What I finally end up doing was replacing the single quote
'
with it code'
using a regex after the stringify() method call the following way:Striking a similar issue using CakePHP to output a JavaScript script-block using PHP's native
json_encode
.$contractorCompanies
contains values that have single quotation marks and as explained above and expectedjson_encode($contractorCompanies)
doesn't escape them because its valid JSON.By adding addslashes() around the JSON encoded string you then escape the quotation marks allowing Cake / PHP to echo the correct javascript to the browser. JS errors disappear.
I understand where the problem lies and when I look at the specs its clear that unescaped single quotes should be parsed correctly.
I am using jquery`s jQuery.parseJSON function to parse the JSON string but still getting the parse error when there is a single quote in the data that is prepared with json_encode.
Could it be a mistake in my implementation that looks like this (PHP - server side):
The final step is that I store the JSON encoded string into an JS variable:
If I use "" instead of '' it still throws an error.
SOLUTION:
The only thing that worked for me was to use bitmask JSON_HEX_APOS to convert the single quotes like this:
Is there another way of tackle this issue? Is my code wrong or poorly written?
Thanks
According to the state machine diagram on the JSON website, only escaped double-quote characters are allowed, not single-quotes. Single quote characters do not need to be escaped:
Update - More information for those that are interested:
Douglas Crockford does not specifically say why the JSON specification does not allow escaped single quotes within strings. However, during his discussion of JSON in Appendix E of JavaScript: The Good Parts, he writes:
So perhaps he decided to only allow strings to be defined using double-quotes since this is one less rule that all JSON implementations must agree on. As a result, it is impossible for a single quote character within a string to accidentally terminate the string, because by definition a string can only be terminated by a double-quote character. Hence there is no need to allow escaping of a single quote character in the formal specification.
Digging a little bit deeper, Crockford's org.json implementation of JSON for Java is more permissible and does allow single quote characters:
This is confirmed by the JSONTokener source code. The
nextString
method accepts escaped single quote characters and treats them just like double-quote characters:At the top of the method is an informative comment:
So some implementations will accept single quotes - but you should not rely on this. Many popular implementations are quite restrictive in this regard and will reject JSON that contains single quoted strings and/or escaped single quotes.
Finally to tie this back to the original question,
jQuery.parseJSON
first attempts to use the browser's native JSON parser or a loaded library such as json2.js where applicable (which on a side note is the library the jQuery logic is based on ifJSON
is not defined). Thus jQuery can only be as permissive as that underlying implementation:As far as I know these implementations only adhere to the official JSON specification and do not accept single quotes, hence neither does jQuery.