8

All keys were double quoted. The whole element was an object. Firefox runs it well but Chrome reports "invalid JSON". Why?

This is full code.

///////////// PHP ////////////////
public function listAlbumAction()
{
    $params = $this->_getAllParams();
    $albums = $this->_album->getAlbumList($params['albumType'], $params['from'], $params['numberOfAlbums']);
    echo json_encode(array("code" => 0, "data" => $albums));
}

///////////////////////////////// JQuery ///////////////////
function loadAlbums()
{
    $.ajax({
        type: 'GET',
        url: '/about-photo/list-album',
        data: {albumType: selectedAlbumType, from: currentPageIndex * numOfAlbumsPerPage, numberOfAlbums: numOfAlbumsPerPage},
        success: function(json) {
            var obj;
            var data;
            try {
                obj = $.parseJSON(json);
                data = obj.data;                                    
            } catch(e) {
                alert(e);
            }               

            if(obj.code == 0) {
                // get number of albums
                var num = data.length;

                // remove old list content
                $('#albumListContent').remove();

                var albumListHTML = '';
                albumListHTML += '<div id="albumListContent">';

                for(var i = 0; i < num; ++i) {                          
                    albumListHTML += '<div id="w' + data[i].album_id + '" class="imgWrapper">';
                    albumListHTML += '<img id="a' + data[i].album_id + 
                                     '" class="albumImg" width="150px" src="' + 
                                     data[i].album_cover + '" alt="not found" title="' + 
                                     data[i].album_name + '"/>';                                             
                    albumListHTML += '<div class="albumTitle">' + data[i].album_name + '</div>';
                    albumListHTML += '</div>';                      
                }

                albumListHTML += '</div>';
                $('#albumListContentWrapper').html(albumListHTML);

                addAlbumHandler();
                addPhotoEffects('.albumImg');                   
                addImgErrorHandler('.albumImg');
            }
        }
    });
}

Edit: JSON output from Chrome (FirebugLite):

    {"code":0,"data":[{"album_id":42,"album_name":"Best album","album_type":"photo","create_date":"09-05-2011 5:48:40","album_cover":"\/x\/media\/6.jpg","description":"Something here"},{"album_id":56,"album_name":"Test album","album_type":"photo","create_date":"09-05-2011 19:27:50","album_cover":"\/x\/media\/44227440_2f1f369517.jpg","description":"apples"},{"album_id":59,"album_name":"Album for something","album_type":"photo","create_date":"10-05-2011 16:19:03","album_cover":"\/x\/media\/apple-howto.jpg","description":"zzz"},{"album_id":62,"album_name":"Vietnam - Thailand - AFF Suzuki cup 2007","album_type":"photo","create_date":"17-05-2011 14:30:32","album_cover":"\/x\/media\/pwjps1231986828.jpg","description":""},{"album_id":63,"album_name":"CS","album_type":"photo","create_date":"17-05-2011 15:24:01","album_cover":"\/x\/media\/apple-logo.jpg","description":""},{"album_id":64,"album_name":"It works","album_type":"photo","create_date":"17-05-2011 15:24:56","album_cover":"\/x\/media\/it_works.png","description":""}]}

JSON output from Firefox (Firebug):

{"code":0,"data":[{"album_id":42,"album_name":"Best album","album_type":"photo","create_date":"09-05-2011 5:48:40","album_cover":"\/x\/media\/6.jpg","description":"Something here"},{"album_id":56,"album_name":"Test album","album_type":"photo","create_date":"09-05-2011 19:27:50","album_cover":"\/x\/media\/44227440_2f1f369517.jpg","description":"apples"},{"album_id":59,"album_name":"Album for something","album_type":"photo","create_date":"10-05-2011 16:19:03","album_cover":"\/x\/media\/apple-howto.jpg","description":"zzz"},{"album_id":62,"album_name":"Vietnam - Thailand - AFF Suzuki cup 2007","album_type":"photo","create_date":"17-05-2011 14:30:32","album_cover":"\/x\/media\/pwjps1231986828.jpg","description":""},{"album_id":63,"album_name":"CS","album_type":"photo","create_date":"17-05-2011 15:24:01","album_cover":"\/x\/media\/apple-logo.jpg","description":""},{"album_id":64,"album_name":"It works","album_type":"photo","create_date":"17-05-2011 15:24:56","album_cover":"\/x\/media\/it_works.png","description":""}]}

I checked it with http://jsonlint.com/ and it says "Valid JSON"

Edit:

Source viewed from Chrome:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
emeraldhieu
  • 9,380
  • 19
  • 81
  • 139
  • 2
    What does your actual JSON output look like? – Demian Brecht May 20 '11 at 02:37
  • Could it be a content-type or encoding issue? – Brett Zamir May 20 '11 at 03:09
  • Just skimming here and I agree with brettz. The JSON looks syntactically correct, and firefox does parse it. Make sure the Content-type header is application/json. I've run into this issue multiple times. I'm not sure if it broke in chrome, but I know firebug wasn't parsing it correctly, As soon as i called header("Content-type: application/json"); – WhiskeyTangoFoxtrot May 20 '11 at 04:25
  • `json_encode()` will send out the proper HTTP header for JSON.. so it can't be that. – Jay Sidri May 20 '11 at 05:48
  • 1
    @Jahufar - eh? `json_encode()` doesn't send any headers; it only produces a string. – Spudley May 20 '11 at 08:16
  • @Spundley: ugh.. had a brain fart there. You're right. I'm used to working with a function that wraps json_encode() and spits out the header with the response. – Jay Sidri May 20 '11 at 08:21
  • 1
    Does [this jsFiddle](http://jsfiddle.net/3W9EG/) work or fail for you? (Works for me in Chrome.) – Matt Gibson May 20 '11 at 08:33
  • 2
    Do you have a Unicode BOM (Byte Order Mark) at the beginning of your PHP file? If so, can you see if your editor can save the file without it and try again? – Matt Gibson May 20 '11 at 08:44
  • 1
    @Matt Gibson: I use Notepad++ to write web pages, I changed them all Utf8 without BOM and it runs successfully! Please post it as an answer and explain me WHY. :D – emeraldhieu May 20 '11 at 09:04
  • I fought with this problem a whole day. Thank you all. @_@ – emeraldhieu May 20 '11 at 09:05
  • 1
    @Emerald214 Done. No problem. Hope the explanation is helpful. You can set Notepad++ to avoid the BOM when creating new files in its Preferences (New Document/Default Directory settings, then choose "UTF-8 without BOM.) That should help prevent this kind of issue in future. – Matt Gibson May 20 '11 at 09:18

3 Answers3

11

You have a Unicode Byte Order Mark at the beginning of your PHP file. Because of this, and because it's before the opening <?php, it gets sent to the client at the beginning of your JSON. This will make your JSON invalid, as those characters shouldn't appear at the beginning of the JSON data. Some browsers cope with it fine; other browsers, such as Chrome, are fussier and complain.

Removing the Byte Order Mark by saving the file without that option set in your editor (how to do this is editor-dependent) will solve your problem.

(You'd probably also find that header() and other PHP functions that send headers wouldn't work in your PHP file, either, giving you the error that output has already started, again because the BOM would have been sent before your PHP started being interpreted.)

Matt Gibson
  • 37,886
  • 9
  • 99
  • 128
2

My guess (based on the difference between the Chrome and Firefox outputs you provided) would be that you've got some leading (or trailing) spaces and/or line breaks sneaking into your PHP output.

You've only provided the PHP for the relevant functions, but check that you haven't got any blank space before or after the <?php and ?> tags, both in your main program and any other PHP files loaded with include() or require().

Its a fairly common problem with PHP code. In a normal HTML page it doesn't really matter (you end up with a load of spurious white space, but it doesn't affect the rendering), but when outputting other types of data it can make the difference between it being valid or not. This is especially true if you're outputting binary data. I've not seen this issue before with JSON, but the blank spaces at the begining of the string you quoted are a classic sign of this sort of thing.

Spudley
  • 166,037
  • 39
  • 233
  • 307
0

try to Encapsulate the JSON (in PHP code) in brackets ... and remove them in the success function of ajax call befor parseJOSN.

helle
  • 11,183
  • 9
  • 56
  • 83