Второй AJAX-вызов по одному и тому же URL-адресу завершается неудачно - но работает случайно и редко - PullRequest
0 голосов
/ 24 мая 2018

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

ReferenceError: getJson is not defined

Но что очень странно для меня, так это то, что второйслой будет добавлен, только иногда.Обновление страницы и повторная попытка почти всегда завершатся неудачей.

Этот код выполняет вызов ajax:

$(document).ready(function() {

...

    $("#add-network-button").on("click", function() {setLocation("Moscow")}) 

    function setLocation(locationName) {

        var networkParameters = {
            service: 'WFS',
            version: '1.0.0',
            request: 'GetFeature',
            typeName: 'netex:' + locationData[locationName].networkWFSName,
            maxFeatures: 99999,
            outputFormat: 'text/javascript',
            format_options: 'callback: getJson'
        };

        addWebService(map, WFSURL, networkParameters)

        var buildingParameters = {
            service: 'WFS',
            version: '1.0.0',
            request: 'GetFeature',
            typeName: 'netex:' + locationData[locationName].buildingWFSName,
            maxFeatures: 99999,
            outputFormat: 'text/javascript',
            format_options: 'callback: getJson'
        };

        addWebService(map, WFSURL, buildingParameters)

    }

А вот функция addWebService:

var addWebService = function(map, WFSURL, WFSParameters) {

    var leafletWFSParameters = L.Util.extend(WFSParameters);

    console.log(WFSURL + L.Util.getParamString(leafletWFSParameters));

    $.ajax({
        url: WFSURL + L.Util.getParamString(leafletWFSParameters),
        dataType: 'jsonp',
        jsonpCallback: 'getJson',
        success: handleJson,
        cache: false
    });

    // TODO: add style
    function handleJson(data) {
        L.geoJson(data, {}).addTo(map);
    }
}

1 Ответ

0 голосов
/ 24 мая 2018

Вы используете jsonp, что означает, что возвращаемые данные - это не JSON, а код javascript, который вызывает глобально определяемую функцию (имя которой определяется jsonpCallback).

jQuery автоматически создает функцию с этим именем, выполняет сетевой запрос и, когда эта функция запускается, уничтожает собственную ссылку из глобальной области.

Вы выполняете два вызова addWebService() в быстрой последовательности, которая запускает два вызова jQuery $.ajax({jsonpCallback: 'getJson'}).Второй вызов перезаписывает глобально определенную функцию обратного вызова getJson.Когда ваш браузер получает первую полезную нагрузку jsonp, глобально определенный обратный вызов getJson уничтожается.Когда вторая полезная нагрузка jsonp получена, она пытается вызвать глобально определенную функцию getJson, и она терпит неудачу.Классическое условие гонки.

Позвольте мне процитировать документацию jQuery для параметра jsonpCallback для $.ajax(), empasis mine:

jsonpCallback

Тип: String или Function ()

Укажите имя функции обратного вызова для запроса JSONP.Это значение будет использоваться вместо случайного имени, автоматически сгенерированного jQuery. Желательно, чтобы jQuery генерировал уникальное имя , поскольку это упростит управление запросами и обеспечит обратные вызовы и обработку ошибок.Возможно, вы захотите указать обратный вызов, если хотите улучшить кэширование запросов GET в браузере.

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

...