Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

parseJSON fails, while json_decode works

Tags:

json

jquery

I've been struggling with this for some time, I have a stringified JSON object stored in DB, once I retrieve it I decode it with both PHP and jQuery, PHP works fine, jQuery fails, heres the code

var data = $.parseJSON('{"page_name":"Test page","page_title":"Test title","site":"0","page_url":"http:\/\/saulius.epickitdev.com\/test-page","page_type":"1","bg_type":"gradient","background_img_url":"","fill_bg_color":"","background_color":"","background_gradient_top":"5194c4","background_gradient_bottom":"000000","video_type":"yt","youtube_video_url":"","youtube_video_start_from":"","mp4_video_url":"","webm_video_url":"","ogg_video_url":"","width_type":"fixed","width_padding":"10","layout_color":"cc25cc","border_size":"3","border_color":"5a7de6","container_position":"middle","container_position_left":"","container_position_right":"","meta_title":"mtest","meta_description":"mdesc","meta_keyword":"mkey","fb_title":"ftitle","fb_description":"fdesc","header_script":{"1":"<meta name=\"keywords\" content=\"h1\">","2":"<meta name=\"keywords\" content=\"h2\">"},"footer_script":[""],"redirect_url":"","exit_message":""}');
        console.log(data);

Now it tells me that the error is:

SyntaxError: JSON.parse: expected ',' or '}' after property value in object at line 1 column 766 of the JSON data

Which would be at the '=' of:

"<meta name=\"keywords\" content=\"h1\">"

Anyone have any clues? I tried different parsers and i'm completely stuck with this!

like image 533
Saulius Antanavicius Avatar asked Aug 20 '14 08:08

Saulius Antanavicius


1 Answers

You need to double encode the \ characters in the String to \\.

var s = '{"page_name":"Test page","page_title":"Test title","site":"0","page_url":"http://saulius.epickitdev.com/test-page","page_type":"1","bg_type":"gradient","background_img_url":"","fill_bg_color":"","background_color":"","background_gradient_top":"5194c4","background_gradient_bottom":"000000","video_type":"yt","youtube_video_url":"","youtube_video_start_from":"","mp4_video_url":"","webm_video_url":"","ogg_video_url":"","width_type":"fixed","width_padding":"10","layout_color":"cc25cc","border_size":"3","border_color":"5a7de6","container_position":"middle","container_position_left":"","container_position_right":"","meta_title":"mtest","meta_description":"mdesc","meta_keyword":"mkey","fb_title":"ftitle","fb_description":"fdesc","header_script":{"1":"<meta name=\\"keywords\\" content=\\"h1\\">","2":"<meta name=\\"keywords\\" content=\\"h2\\">"},"footer_script":[""],"redirect_url":"","exit_message":""}'
$.parseJSON(s)

This is because they are escapes inside a string, inside a string.

The top level string is the whole value, so unwrapping one level of escaping leads to this,

{"1":"<meta name="keywords" content="h1">"} #Invalid JSON

This is invalid because the quotes in the value are no longer escaped, since the top level JavaScript string unwrapped them. When that string literal is read in by the JavaScript interpreter, all the \ characters are unwrapped one level, which means that \" becomes just ". Then the JSON string needs to be processed, but it is no longer valid, since the quotes that you intended to escape, are now unescaped (In reality they were never really escaped, they just seemed that way.) When you use single quotes, you don't need to escape ", but you can always escape anything, if it isn't a special character it just does nothing.

So in order to have the quotes still be escaped after the top level string is processed, you need to escape the \ itself.

var s = '{"1":"<meta name=\\"keywords\\" content=\\"h1\\">"}'
console.log(s) //'{"1":"<meta name=\"keywords\" content=\"h1\">"}'
$.parseJSON(s)
like image 165
isomarcte Avatar answered Oct 07 '22 01:10

isomarcte