Проблема Javascript getJSON с использованием обратного вызова Django

Я пытаюсь выполнить вызов с помощью этого скрипта, но получаю сообщение "Uncaught SyntaxError: Unexpected token:"

Я не могу понять, где я ошибаюсь, я не знаю, связано ли это с моим обратным вызовом. Я отправляю действительный пакет JSON, поэтому не думаю, что это проблема. В любом случае, вот мой вызов html/jquery:

<script>
function loadJSON(){
    $.getJSON("http://localhost:8000/api/0.1/tonight-mobile.json&callback=?", function(data){
            alert('hey');
             $('result').append(data);
             alert('hey 2'); 
         $.each(data, function(i, json){});

    });
    alert('hey 3');
}
</script>

С этой соответствующей функцией в моем представлении django:

def tonight_mobile(request):

    callback = request.GET.get('callback', '')

    def with_rank(rank, place):
        return (rank > 0)

    place_data = dict(
        Places = [make_mobile_place_dict(request, p) for p in Place.objects.all()]
    )

    xml_bytes = json.dumps(place_data)
    return HttpResponse(xml_bytes, content_type='application/json; charset=utf-8')

Вот мой запрос, зарегистрированный моим сервером (поэтому я знаю, что он, по крайней мере, зашел так далеко с кодом состояния OK):

"GET /api/0.1/tonight-mobile.json&callback=jsonp1293142434434 HTTP/1.1" 200 167

Отображение этой ошибки в моей консоли javascript:

Uncaught SyntaxError: Unexpected token : tonight-mobile.json&callback=jsonp1293142434434:1

Если вам нужно увидеть мой формат JSON (если это является причиной этого), пожалуйста, дайте мне знать, и я тоже могу его опубликовать.

Заранее спасибо за вашу помощь!


ОБНОВЛЕНИЕ:

Вот ответ с моего сервера:

{"Places": [{"url": "http://localhost:8000/api/0.1/places/1.plist", "image_url": "http://localhost:8000/static/place_logos/Tsonoqua_Mask.gif", "name": "Boo's Place"}]}
[23/Dec/2010 17:37:22] "GET /api/0.1/tonight-mobile.json&callback=jsonp1293147441552 HTTP/1.1" 200 167

ОБНОВЛЕНИЕ 2:

Мне удалось заставить мой обратный вызов работать правильно! Вот код:

Сторона клиента:

<script>
function loadJSON(){
    $.getJSON("http://localhost:8000/api/0.1/tonight-mobile.json&callback=?", logIt(data));
}
function logIt(data){
    window.console && console.log(data);
    alert('yay!');
}
</script>

Сторона сервера:

def tonight_mobile(request):
    callback = request.GET.get('callback', 'logIt')

    def with_rank(rank, place):
        return (rank > 0)

    place_data = dict(
        Places = [make_mobile_place_dict(request, p) for p in Place.objects.all()]
    )

    xml_bytes = json.dumps(place_data)

    if callback:
        xml_bytes = '%s(%s)' % (callback, xml_bytes)
    print xml_bytes

    return HttpResponse(xml_bytes, content_type='application/javascript; charset=utf-8')

Это возвращает следующий ответ:

logIt({"Places": [{"url": "http://localhost:8000/api/0.1/places/1.plist", "image_url": "http://localhost:8000/static/place_logos/Tsonoqua_Mask.gif", "name": "Boo's Place"}]})

Это так должно работать? Кажется, я должен быть в состоянии упростить вызов getJSON... Я просто хочу убедиться, что сделал все, что мне нужно, правильно с моим обратным вызовом, прежде чем я продолжу анализировать ответ и устанавливать их для элементов на странице.


ОБНОВЛЕНИЕ 3*

Итак, я добился некоторого прогресса!! Я использую мобильный Jquery, поэтому игнорируйте некоторые из следующих чрезмерных CSS, это не связано с основной проблемой.

У меня возникла проблема с циклическим просмотром "Мест" в моем пакете JSON. Я получаю ответ с несколькими «Местами», но не могу понять, как их перебирать. Моя переменная «i» в каждом цикле работает правильно для первого элемента и отображает соответствующее имя и изображение.

Мой метод getJSON и обратного вызова превратился в это:

<script>
function loadJSON(){
    $.getJSON("http://localhost:8000/api/0.1/tonight-mobile.json&callback=?", callback(data));
}
function callback(data){
    $("#tonight-list").each(data.Places, function(i) {
        $(this).append("<li role='option' tabindex='" + data.Places[i] + "' class='ui-li-has-thumb ui-li ui-btn ui-btn-icon-right ui-corner-top ui-corner-bottom ui-controlgroup-last ui-btn-down-c ui-btn-up-c' data-theme='c'><div class='ui-btn-inner ui-corner-top ui-corner-bottom ui-controlgroup-last'><span class='ui-icon ui-icon-arrow-r'></span><div class='ui-btn-text'><img src=" + data.Places[i].image_url + " alt=" + data.Places[i].name + " class='ui-li-thumb ui-corner-tl ui-corner-bl'/><h1 class='list-title ui-li-heading' id='list-title'><a href='detail.html?id=slide' data-transition='slide' class='ui-link-inherit'>" + data.Places[i].name + "</a></h1><span class='ui-li-count ui-btn-up-c ui-btn-corner-all'>" + data.Places[i].events + " events</span></div></div></li>");
    });

}
</script>

Вот мой ответ:

callback({"Places": [{"url": "http://localhost:8000/api/0.1/places/3.plist", "image_url": "http://localhost:8000/static/place_logos/Bengals_1.png", "name": "Big 12", "events": 2}, {"url": "http://localhost:8000/api/0.1/places/2.plist", "image_url": "http://localhost:8000/static/place_logos/Makonde_Mask.gif", "name": "Harpo's", "events": 0}, {"url": "http://localhost:8000/api/0.1/places/1.plist", "image_url": "http://localhost:8000/static/place_logos/Quintons_1.png", "name": "Quinton's", "events": 1}]})

Могу ли я сбить с толку, как каждая функция перебирает объекты JSON (которые становятся) объектами Javascript? Я почти уверен, что каждая из них - моя проблема, так как я получаю только ПЕРВЫЙ элемент списка "Места". Кто-нибудь может мне помочь?


person user546459    schedule 23.12.2010    source источник
comment
Да, проблема в ответе, вы возвращаете JSON, а не JSONP.   -  person Nick Craver    schedule 24.12.2010


Ответы (3)


Да, чтобы вернуть jsonp, вам нужно обернуть ответ функцией:

def tonight_mobile(request):

    callback = request.GET.get('callback')

    def with_rank(rank, place):
        return (rank > 0)

    place_data = dict(
        Places = [make_mobile_place_dict(request, p) for p in Place.objects.all()]
    )

    xml_bytes = json.dumps(place_data)
    if callback:
        xml_bytes = '%s(%s)' % (callback, xml_bytes)
    return HttpResponse(xml_bytes, content_type='application/json; charset=utf-8')
person keegan3d    schedule 23.12.2010
comment
Затем, на моей стороне клиента, как я могу ссылаться на эту обернутую функцию? Я не понимаю, как моя функция в getJSON этого не делает... - person user546459; 24.12.2010
comment
Ваш клиентский код уже выглядит правильно. Если URL-адрес включает строку callback=? (или аналогичный, как определено серверным API), запрос обрабатывается как JSONP вместо api. jquery.com/jQuery.getJSON. Это отличная статья о json и jsonp: javascriptweblog.wordpress.com /2010/11/29/json-and-jsonp - person keegan3d; 24.12.2010
comment
Если json и веб-страница, запрашивающая json, находятся в одном домене, вам не нужно использовать их как jsonp. en.wikipedia.org/wiki/Same_origin_policy - person keegan3d; 24.12.2010
comment
Спасибо за полезную ссылку keegan3d (javascriptweblog) - это действительно прояснило мне ситуацию, чтобы понять, КАК все должно было работать. :) В документации Jquery API недостаточно подробностей о функциях обратного вызова. Я обновил свою текущую ситуацию, если бы вы могли взглянуть на обновление 2 и ответить, я был бы очень признателен! - person user546459; 24.12.2010
comment
Я обновил свой вопрос с довольно большим прогрессом и мог бы немного помочь моему итератору. см. выше - person user546459; 11.01.2011
comment
С каждым вам не нужно использовать i, вы можете использовать this для ссылки на элемент внутри функции, посмотрите этот пример: jsfiddle.net/keegan3d/MJw4h - person keegan3d; 12.01.2011

Выглядит хорошо, вы можете упростить вызов getJSON следующим образом:

function loadJSON(){
    var url = "http://localhost:8000/api/0.1/tonight-mobile.json&callback=?";
    $.getJSON(url, function(data){
        if(data){
            console.log(data.name);
        }
    });
}

В вашем коде Python я бы сделал

callback = request.GET.get('callback')

вместо

callback = request.GET.get('callback', 'logIt')

поэтому, если обратный вызов не предоставлен, вместо jsonp будет возвращен json.

person keegan3d    schedule 25.12.2010
comment
Эй, киган, я опубликовал еще одно обновление для своего первоначального вопроса, вместо того, чтобы загромождать SO жаргоном. :) Если бы вы могли дать мне какое-то направление с моим итератором, это было бы здорово. :) - person user546459; 11.01.2011

Вы смешиваете JSON и JSONP. Ваш скрипт Django возвращает объект JSON, когда jQuery ожидает объект JSON, обернутый аргументом обратного вызова:

callback(JSON string);

person Ian Wetherbee    schedule 23.12.2010
comment
Я обновил свою текущую ситуацию и думаю, что правильно делаю свой обратный вызов, хотя кажется, что я должен упростить вызов функции обратного вызова на стороне клиента? - person user546459; 24.12.2010