4

I have read through many, many Q&A of the same issue, but none have my specific issue (at least not that I could find).

I have a php script that echos back a json string

header('Content-Type: application/json');
echo $result;

JSON returned (checked with JSONLint and is valid):

{"Announcement":{"ID":1,"Type":1,"Text":"This is a test Albums announcement.","TimeStart":"1969-12-31","TimeEnd":"1969-12-31"}}

And a web jquery script that reads the json:

$.ajax({
        type : "GET",
        url : "http://b***s.net/S****s/GetAnnouncements.php?callback=?",
        data : {get_param : "Announcement"},
        dataType : "json",
        error : function(jqXHR, textStatus, errorThrown) {alert(errorThrown); alert(textStatus);},
        success : function(data) {alert('success');
            $.each(data, function(index, element) { alert('here');
                $("#announcements-list").append("<li><a id='announcements-a-" + element.ID + "' href='#announcement-details'><p>" + element.Type + ": " + element.Text + "</p></a></li>");
                $("#announcements-a-" + element.ID).bind('click', function() {Announcements.AnnouncementID = element.ID;});
            });
            $("#announcements-list").listview('refresh');
        }
    });

success: is never called. And error: returns a textStatus of "parsererror" and errorThrown is "Error: jQuery1830649454693285679_1359620502896 was not called"

  • I have added callback=? to the url to work around the cross-domain issue.
  • I have sent header('Content-Type: application/json'); to the php, and it returns NO html.
  • I have verified JSON validity with JSONLint
  • I have tried removing the data: "json" as some answers say, but that still returns a parsererror
  • Using jQuery 1.8.3
Salman A
  • 262,204
  • 82
  • 430
  • 521
SnareChops
  • 13,175
  • 9
  • 69
  • 91
  • @salmanA Yes it should, and I feel embarassed... Though, that unfortunately did not change the outcome... :( – SnareChops Jan 31 '13 at 08:58
  • 1
    Just adding the `callback=?` doesn't automatically go around cross-domain issues... The server must return JSONP for it to work. (Otherwise it wouldn't be much of a security feature.) – JJJ Jan 31 '13 at 09:07
  • @Juhana Now that it's been mentioned I knew what to search for and am adding the modifications to my php now. – SnareChops Jan 31 '13 at 09:10

2 Answers2

4

Your server and client scripts do not complement each other. You have two options:


Make your server side script return JSON:

Content-Type: application/json

{"Announcement":{"ID":1}}

And omit the callback parameter:

$.ajax({
    type : "GET",
    url : "http://example.com/feed/json.php",
    dataType : "json"
});

Make your server side script return JSONP i.e. JSON wrapped in a callback function:

Content-Type: application/javascript

jQuery_xxxxxxxx({"Announcement":{"ID":1}});

And change datatype to jsonp:

$.ajax({
    type : "GET",
    url : "http://example.com/feed/json.php",
    dataType : "jsonp"
});

Note that jQuery silently appends &callback=jQuery_xxxxxxxx to the URL for such requests. The server should use the callback name specified in the URL. You can do something like this:

echo sprintf(
    "%s(%s);",
    isset($_GET["callback"]) ? $_GET["callback"] : "void",
    json_encode($data)
);
Salman A
  • 262,204
  • 82
  • 430
  • 521
  • Thank you for pointing me in the right direction. I used the answer [here](http://stackoverflow.com/questions/1678214/javascript-how-do-i-create-jsonp) (which is the same as yours) And it works beautifully now. – SnareChops Jan 31 '13 at 09:13
2

I've just try and here is the solution tested in cross domain

$.ajax({
    type : "GET",
    url : "http://******/14621356.php",
    data : {get_param : "Announcement"},
    dataType : "jsonp",
    error : function(jqXHR, textStatus, errorThrown) {alert(errorThrown); alert(textStatus);},
    success : function(data) {alert('success');
        $.each(data, function(index, element) { alert('here');
            $("#announcements-list").append("<li><a id='announcements-a-" + element.ID + "' href='#announcement-details'><p>" + element.Type + ": " + element.Text + "</p></a></li>");
            $("#announcements-a-" + element.ID).bind('click', function() {Announcements.AnnouncementID = element.ID;});
        });
        $("#announcements-list").listview('refresh');
    }
});

And for the php

header('Content-Type: application/json');
echo $_GET['callback'].'('.'{"Announcement":{"ID":1,"Type":1,"Text":"This is a test Albums announcement.","TimeStart":"1969-12-31","TimeEnd":"1969-12-31"}}'.')';

Take care of jsonp in dataType.

Spin0us
  • 333
  • 3
  • 9
  • It was the `echo $_GET['callback'] . "(" . $json . ");"` part that I was missing. I didn't know that you had to echo it back in a function. Thanks. – SnareChops Jan 31 '13 at 09:16