Динамический подход JSONP

Мне было интересно, правильный ли мой подход к JSONP, и если нет, то что я могу изменить.

Мой стандартный подход JSONP:

Сервер

Стандартный параметр ?jsonp=обратного вызова

Клиент

  1. Вызов функции (пример: jsonp(url, callback)) *1
  2. Создайте тег <script> *2
  3. Выполнить скрипт
  4. Удалить тег скрипта

Код
Примечание. Я только что написал все это в редакторе stackoverflow, код не тестировался
1:

jsonp("http://example.com/sampleAPI", function(result) {  
    // Do something  
});

2:

var callbackID = 0;
var jsonp = function(url, callback) {
    var callbackName = 'callback' + callbackID;
    // put the callback in the URL
    callbackID++;
    if (url.indexOf('?') != -1) {
        url += '&jsonp=' + callbackName;
    } else {
        url += '?jsonp=' + callbackName;
    }

    // create the callback
    window[callbackName] = function(result) {
        $('jsonpScriptElement' + callbackID).remove();
        callback(result);
        window.splice(callbackName);
    }

    // Create the actual element (do this as the last thing because of caching)
    // Assuming prototype.js usage
    $$('body')[0].insert(new Element('script', {'href': url, 'id': 'jsonpScriptElement' + callbackID}));
}

person Tom van der Woerdt    schedule 28.04.2011    source источник
comment
Теперь, когда я смотрю на это: может быть, мне следует добавить onError в тег скрипта. Я уверен, что есть и другие вещи, которые можно изменить, хотя :-)   -  person Tom van der Woerdt    schedule 29.04.2011


Ответы (1)


Единственная проблема, которую я вижу, это эта часть:

window[callbackName] = function(result) {
    $('jsonpScriptElement' + callbackID).remove();
    callback(result);
    window.splice(callbackName);
}

Вы создаете новую функцию для каждого звонка, который вы делаете. Постарайтесь избежать этого, создав универсальную функцию, которую можно безопасно использовать в асинхронном режиме. Не должно быть слишком сложно что-то придумать. Например, вы можете передать порядковый номер в вызов JSONp и обратно в обратный вызов, чтобы вы могли разделить разные запросы.

И да, JSONp действительно так прост :P

Кроме того, вы можете изменить свою функцию JSONp на это:

var jsonp = (function() {
    var callbackID = 0;
    return function (url, callback) {
         //.. function body ..
    }
}());

Таким образом, вам не нужно объявлять callbackID в глобальной области видимости.

person Halcyon    schedule 28.04.2011