Пытаюсь получить доступ к API stackoverflow, но получаю ошибку синтаксического анализа

Пытаясь использовать API stackoverflow с ajax и jquery, я просто не могу заставить его работать. Я знаю, что должен использовать jsonp в качестве типа данных, и я продолжаю читать различные способы выполнения запроса jsonp, но я все еще не могу заставить его работать.

Это мой запрос ajax:

var API_KEY = "XXXXXXXXXXXX";
var URL = "http://api.stackoverflow.com/1.1/";

var _url = URL + 'users?filter=locrizak';

$.ajax({
    dataType:'jsonp',
    jsonp : false,
    jsonpCallback : "onJsonp",
    url: _url,
    success: function(val) {
            console.log('success');
        //console.log(val);
    },
    error: function(val) {
        console.log('error');
        console.log(arguments);

    }
});

function onJsonp() {
    console.log(arguments);
};

Что бы я ни пытался, я всегда получаю этот ответ в firebug:

"parsererror" "onJsonp was not called"

Я знаю, что делаю что-то действительно глупое, потому что столкнулся с теми же проблемами при попытке использовать Twitter API, но я не могу в жизни вспомнить, что я сделал, чтобы заставить его работать.

Обновлять

Поэтому я взял рабочую демо-версию loog @genesis и попробовал ее несколько раз разными способами, но безуспешно. Затем я заметил свою версию jQuery и переключил ее на ту, которую использовал он, и она волшебным образом сработала.

Я меняю самую последнюю версию http://code.jquery.com/jquery-1.6.2.min.js на http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js

хм, понятия не имею, почему это работает, возможно, ошибка, но кто знает, может быть, что-то еще изменилось.

Если кто-нибудь знает, почему было бы здорово, если бы вы могли объяснить. Также я понимаю, что jQuery автоматически добавляет обратный вызов, но я не мог заставить его работать так. Что я мог сделать, чтобы это заработало, я думаю, вы бы сказали «более правильный» способ?

var URL = "http://api.stackoverflow.com/1.1/";
api.get(URL + 'users?filter=locrizak');
api.get = function(url) {
    $.ajax({
        /*dataType:'jsonp',*/
        dataType:'json',
        jsonp : false,
        url: url + '&jsonp=api.onJsonp',
        success: function(val) {
            console.log('success');
            //console.log(val);
        },
        error: function(val) {
            //error gets called but.......
            console.log(arguments);
            console.log('error');
            console.log(val);
        }
    });

};
api.onJsonp = function() {
    //so does the callback!!  
    console.log('called');
    console.log(arguments);
}
//note this code is simplified

person locrizak    schedule 22.07.2011    source источник
comment
Плохое название вопроса. Можете ли вы сделать это описать вопрос? Ваши предыдущие заголовки вопросов приличные.   -  person Lightness Races in Orbit    schedule 23.07.2011
comment
Получил это работает. Пожалуйста, смотрите мой обновленный ответ :-)   -  person andyb    schedule 23.07.2011


Ответы (4)


Вы можете добавить jsonp:'jsonp', к вызову ajax(). В документации API stackoverflow указано, что ему нужен параметр запроса jsonp, а свойство jQuery для настройки переданного параметра строки запроса называется jsonp . Без него по умолчанию в конец URL-адреса добавляется callback=?.

Я получаю success в консоли, запуская это:

var URL = "http://api.stackoverflow.com/1.1/";
var _url = URL + 'users?filter=locrizak';

$.ajax({
    dataType: 'jsonp',
    jsonp: 'jsonp', // <--- add this
    url: _url,
    success: function(val) {
       console.log('success');
    },
    error: function(val) {
        console.log('error');
        console.log(arguments);
    }
});

Кроме того, jsonp:false, не должно быть установлено на false; он должен быть true, в противном случае параметр строки запроса не добавляется.

Обновление: он правильно работает с jQuery v1.6.2 и с использованием правильных параметров, как описано в моем исходном ответе выше. Функция обратного вызова должна быть вне анонимной функции jQuery.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <title>JSONP Test</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(function(){
            $.ajax({
                dataType:'jsonp',
                jsonp: 'jsonp',
                jsonpCallback: 'onJsonp',
                url: 'http://api.stackoverflow.com/1.1/users?filter=locrizak',
                success: function(data) {
                    console.log('success', data);
                },
                error: function(data) {
                    console.log('error', data);
                }
            });
        });

        function onJsonp(data) {
            console.log('callback', data);
        };
    </script>
</head><body></body></html>

Обновление 2: На основе комментариев вот еще одна версия, на этот раз завернутая в объект. Обратите внимание, что вы не можете использовать jsonpCallback: 'api.onJsonp',, потому что это определено только внутри анонимной функции jQuery. Самый простой способ сохранить инкапсуляцию — создать глобальную функцию и просто передать управление обратно ее аналогу api.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <title>JSONP Test</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(function(){
            api = {
                get: function(url) {
                    var URL = "http://api.stackoverflow.com/1.1/";
                    $.ajax({
                        dataType: 'jsonp',
                        jsonp: 'jsonp',
                        jsonpCallback: 'onJsonp',
                        url: URL + url,
                        success: function(data) {
                            console.log('success', data);
                        },
                        error: function(data) {
                            console.log('error', data);
                        }
                    });
                },
                onJsonp: function(data) {
                    console.log('callback', data);
                }
            }

            api.get('users?filter=locrizak');
        });

        function onJsonp(data) {
            api.onJsonp(data);
        }
    </script>
</head><body></body></html>
person andyb    schedule 22.07.2011
comment
Красивый! Только одна маленькая проблема. Я заставил его работать с глобальной функцией. Я получаю успех, и вызывается метод onJsonp. Как только я меняю onJsonp на api.onJsonp, вызывается обратный вызов, но срабатывает обработчик ошибок ajax. - person locrizak; 23.07.2011
comment
в качестве решения baidaid я поместил api.onJsonp.apply(api, arguments); в глобальную функцию onJsonp, но я бы предпочел вызвать api.onJsonp в качестве обратного вызова запроса и получить успешный ответ. - person locrizak; 23.07.2011
comment
@locrizak то, что вы хотите, невозможно, я думаю, из-за того, что api.onJsonp существует только в анонимном закрытии jQuery. Я обновил свой ответ улучшенным примером, который должен делать то, что вы хотите. - person andyb; 24.07.2011
comment
Да, это то, о чем я думал, просто проверяя, не пропустил ли я что-нибудь, что я должен сделать, чтобы заставить его работать. Спасибо за вашу помощь - person locrizak; 24.07.2011

Вы должны позвонить

http://api.stackoverflow.com/1.1/users?filter=locrizak&jsonp=jsonp

рабочая демонстрация и код:

<script>
var URL = "http://api.stackoverflow.com/1.1/";
var api;
api = {
    get: function(url) {
        $.ajax({

            dataType: 'json',
            jsonp: false,
            jsonpCallback: 'api.onJsonp',
            url: url + '&jsonp=api.onJsonp',
        });
    },
    onJsonp: function(val) {
        $("body").prepend(val.users[0].reputation);
        console.log('called');

    }
}

api.get(URL + 'users?filter=locrizak');

//note this code is simplified</script>
person genesis    schedule 22.07.2011
comment
извините, у меня есть пара закрытий, и это упрощено, исправлено сейчас - person locrizak; 23.07.2011
comment
@ShankarSangoli: прошло несколько секунд - person genesis; 23.07.2011
comment
Существует свойство для настройки этого объекта ajax(). jQuery может автоматически добавлять параметр строки запроса в конец URL-адреса. - person andyb; 23.07.2011
comment
@генезис. Здорово! Я обновил свой вопрос, но это заставило меня иметь еще пару. - person locrizak; 23.07.2011

Определен ли onJsonp внутри замыкания? Если это так, возможно, проблема заключается в том, что вы ссылаетесь на обратный вызов по имени ('onJsonp'), а не по ссылке?

Два решения: либо определить onJsonp в глобальной области видимости, либо передать его по ссылке, удалив кавычки.

person searlea    schedule 22.07.2011
comment
Я пробовал api.onJsonp... api как имя закрытия, а также глобальный метод onJsonp. Вы не можете передать имя функции без кавычек, это должна быть строка, потому что она добавляется в запрос, а не вызывается сразу. - person locrizak; 23.07.2011

$.ajax({
    dataType:'jsonp',
    jsonp : true,
    jsonpCallback : "onJsonp",
    url: _url,
    success: function(val) {
            console.log('success');
        //console.log(val);
    },
    error: function(val) {
        console.log('error');
        console.log(arguments);

    }
});

установите для jsonp значение true.

person DrStrangeLove    schedule 22.07.2011
comment
Это не работает. В документах jQuery ajax говорится, что нужно установить функцию обратного вызова или false, если функция обратного вызова добавит дополнительный ?=, и в этом случае он будет - person locrizak; 23.07.2011