PDA

View Full Version : [INFOREQ]Json decoding results in error in FireFox



Snape
25 Mar 2010, 4:51 AM
Code sample from PHP:


<?= json_encode(array('test' => 'a/b'))


Code sample from JS:


var value = Ext.decode(json);


Result: JavaScript error in FireFox.

The problem is that ExtJS uses eval() to reconstruct JSON object. This does not work if json text contains a forward slash escaped by a backslash. Here is the example of such correct (!) JSON:



{"test":"a\/b"}


When eval'ing such string escaping is broken and FireFox shows JavaScript error.

ExtJS needs some other way to decode JSON correctly. For example, this parser: http://www.json.org/json.js

Snape
25 Mar 2010, 4:53 AM
I forgot to write that this json is return using traditional submission with a file–based upload and text/html content type.

evant
25 Mar 2010, 5:12 AM
Not sure what you're getting at.

I can put the following in Firebug:



console.log(Ext.decode('{"test":"a\/b"}'));


No crash.

Snape
25 Mar 2010, 5:35 AM
I tracked down the problem. It seems to be FireFox issue, not ExtJS. As soon as I send a response as text/html, I get a "beautified" response in XHTTPRequest in FireFox. What a stupid thing...

Here is what server sends (checked with a local proxy):


{"success":false,"errors":[{"id":"signature","msg":"\u0160\u0101du linku ievietot aizliegts: http:\/\/line.world-of-love.ru\/userlines\/45_94_1192046400_1_Karlitim_0_0_0 <br \/> \u0160\u0101du linku ievietot aizliegts: http:\/\/line.world-of-love.ru\/userlines\/20_81_1058558400_1_Precejushies_1_0_0"}],"error":"L\u016bdzu, p\u0101rbaudiet ievad\u012bto inform\u0101ciju atz\u012bm\u0113tos laukos."}


In XHHTPRequest it becomes:


{"success":false,"errors":[{"id":"signature","msg":"\u0160\u0101du linku ievietot aizliegts: http:\/\/line.world-of-love.ru\/userlines\/45_94_1192046400_1_Karlitim_0_0_0 <br \/=""> \u0160\u0101du linku ievietot aizliegts: http:\/\/line.world-of-love.ru\/userlines\/20_81_1058558400_1_Precejushies_1_0_0"}],"error":"L\u016bdzu, p\u0101rbaudiet ievad\u012bto inform\u0101ciju atz\u012bm\u0113tos laukos."}

That cannot be parsed by eval().

If anybody got a clue how I can send HTML and get it non–parsed in XHHTPRequest, you are welcome to enlighten me :) Thanks in advance.

Snape
25 Mar 2010, 5:36 AM
(response awaits moderation because I posted some links. hope it passes through)

Condor
25 Mar 2010, 5:46 AM
The response isn't HTML, so why would you set the Content-type to text/html? The correct Content-type for JSON data is application/json.

Or is this the response for a file upload? In that case the result must indeed have Content-type text/html because it is loaded in an IFRAME. For file uploads you should format your JSON data as the value of a textarea, e.g.

<html><body><textarea>{abc: 'xyz'}</textarea></body></html>

Snape
25 Mar 2010, 5:59 AM
Yes, it is a file upload. The data is correctly sent to server and response is correctly returned (I see that with the HTTP proxy). However <br /> becomes <br \/=""> in response.responseText. This is strange. Server output is correct but it is different in response.responseText. I think FireFox tries to beautify HTML or something like that, assumes that \/ is an attribute and adds ="". Why does it do that with text/html content type? Who knows...

Basically I have to change server output to use <br> instead of <br />. That fixed the issue. Hope it helps somebody else.

You can close this thread. However I think it is worth keeping it because somebody else may have the same issue.

I appologize for false error report but at least I added to common knowledge :)

mschwartz
25 Mar 2010, 6:27 AM
A file upload is not done via XHR, but through an invisible iframe. The response object is faked by Ext under the hood. It basically scrapes the responseText from the iframe.

Since you have set the content type to text/html, the browser is interpreting the JSON string as HTML. It's just a bunch of ascii characters and you happen to have some embedded HTML in your JSON so that gets processed by the browser.

The guys at Ext a long time ago figured out that you can put the JSON within <textarea></textarea> and it doesn't get processed by the browser, but they have to parse out the textarea tags when scraping the responseText/iframe.

Your fix of removing the / from the <br /> tag is a shallow one. You will run into similar problems later on with any other HTML you may be sending within JSON strings in this manner.

Snape
25 Mar 2010, 7:09 AM
Hmm. Does that work in ExtJS if I put tags in <textarea>?

Condor
25 Mar 2010, 7:15 AM
Yes, Ext 3 uses the textarea value if it is the first node in the body.

(now you only have to take care that your JSON data doesn't contain </textarea> )

Snape
25 Mar 2010, 7:50 AM
Condor, thank you very much! :)

ExtJS rocks!!!