Динамический подход JSONP - PullRequest
1 голос
/ 29 апреля 2011

Мне было интересно, правильный ли мой подход к 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}));
}

1 Ответ

3 голосов
/ 29 апреля 2011

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

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 в глобальной области видимости

...