请求JSONP GeoServer的多个AJAX调用



我有一个代码,我从geoserver请求数据,并在地图上显示geoJSON。对于这个请求,我使用了如下三个AJAX调用:

$(document).ready(function(){
//BASEMAP
var center = new L.LatLng(-0.8936,119.8638);
var map = new L.Map('map', { center: center, zoom: 14, attributionControl:true, zoomControl:false});
osmTile = "http://tile.openstreetmap.org/{z}/{x}/{y}.png";
osmCopyright = "Map data © 2016 OpenStreetMap contributors";
osmLayer = new L.TileLayer(osmTile, { maxZoom: 18, attribution: osmCopyright } );
map.addLayer(osmLayer);

//URL SERVICE
var owsrootUrl = 'http://sample.com/geoserver/ows';
//different color in layers
function getColor(d) {
    return d > 10000 ? '#FF0000' :
       d > 5000 ? '#FF9900' :
       d > 2000 ? '#E31A1C' :
       d > 1000 ? '#00FF00' :
       d > 500  ? '#FD8D3C' :
       d > 200  ? '#0000CC' :
       d > 100  ? '#FED976' :
                  '#FFEDA0';
}
function style(feature) {
    return {
        weight: 1,
        opacity: 3,
        color: 'white',
        dashArray: '3',
        fillOpacity: 3,
        fillColor: getColor(feature.properties.luas_tanah)
    };
}
var lyr_1 = new L.LayerGroup();
var lyr_2 = new L.LayerGroup();
var lyr_3 = new L.LayerGroup();
var lyr_4 = new L.LayerGroup();
var defaultParameters = {
    service : 'WFS',
    version : '1.0.0',
    request : 'GetFeature',
    typeName : 'pbb:view_map',
    maxFeatures: 1000,
    outputFormat : 'text/javascript',
    format_options : 'callback:getJson',
    SrsName : 'EPSG:4326'
};
var parameters = L.Util.extend(defaultParameters);
var URL = owsrootUrl + L.Util.getParamString(parameters);
var lyr_1 = new L.LayerGroup();
var ajax1 = $.ajax({
    type: 'GET',
    url : URL,
    dataType : 'jsonp',
    async: false,
    jsonpCallback : 'getJson',
    success : function (response) {
        console.log("Layer 1");
        L.geoJson(response, {
            style: function (feature) {
                return {
                    stroke: true,
                    color: getColor(feature.properties.luas_tanah),
                    opacity: 1,
                    weight: 1
                };
            },
            onEachFeature: function (feature, layer) {
                popupOptions = {maxWidth: 200};
                layer.bindPopup("<b>D NOP : </b> " + feature.properties.d_nop                        
                    ,popupOptions);
            }
        }).addTo(lyr_1);
    },
    error: function (xhr, status) {
        alert("Failed call Layer A");
    }
});
var defaultParameters1 = {
    service : 'WFS',
    version : '1.0.0',
    request : 'GetFeature',
    typeName : 'pbb:view_map',
    maxFeatures: 1000,
    outputFormat : 'text/javascript',
    format_options : 'callback:getJson',
    SrsName : 'EPSG:4326'
};
var parameters1 = L.Util.extend(defaultParameters1);
var URL1 = owsrootUrl + L.Util.getParamString(parameters1);
var lyr_2 = new L.LayerGroup();
var ajax2 = $.ajax({
    type: 'GET',
    url : URL1,
    dataType : 'jsonp',
    async: false,
    jsonpCallback : 'getJson',
    success : function (response) {
        console.log("Layer 2");
        L.geoJson(response, {
            style: function (feature) {
                return {
                    stroke: true,
                    color: getColor(feature.properties.luas_tanah),
                    opacity: 0.8,
                    weight: 1
                };
            },
            onEachFeature: function (feature, layer) {
                popupOptions = {maxWidth: 200};
                layer.bindPopup("<b>D NOP : </b> " + feature.properties.d_nop
                    ,popupOptions);
            }
        }).addTo(lyr_2);
    },
    error: function (xhr, status) {
        alert("Failed call Layer B");
    }
});
var defaultParameters2 = {
        service : 'WFS',
        version : '1.0.0',
        request : 'GetFeature',
        typeName : 'pbb:view_map',
        maxFeatures: 1000,
        outputFormat : 'text/javascript',
        format_options : 'callback:getJson',
        SrsName : 'EPSG:4326'
    };
var parameters2 = L.Util.extend(defaultParameters2);
var URL2 = owsrootUrl + L.Util.getParamString(parameters2);
var lyr_3 = new L.LayerGroup();
var ajax3 = $.ajax({
    type: 'GET',
    url : URL2,
    dataType : 'jsonp',
    async: false,
    jsonpCallback : 'getJson',
    success : function (response) {
        console.log("Layer 3");
        L.geoJson(response, {
            style: function (feature) {
                return {
                    stroke: true,
                    color: getColor(feature.properties.luas_tanah),
                    opacity: 0.8,
                    weight: 1
                };
            },
            onEachFeature: function (feature, layer) {
                popupOptions = {maxWidth: 200};
                layer.bindPopup("<b>D NOP : </b> " + feature.properties.d_nop 
                    ,popupOptions);
            }
        }).addTo(lyr_3);
    },
    error: function (xhr, status) {
        alert("Failed call Layer C");
    }
});
var defaultParameters3 = {
        service : 'WFS',
        version : '1.0.0',
        request : 'GetFeature',
        typeName : 'pbb:view_map',
        maxFeatures: 1000,
        outputFormat : 'text/javascript',
        format_options : 'callback:getJson',
        SrsName : 'EPSG:4326'
    };
var parameters3 = L.Util.extend(defaultParameters3);
var URL3 = owsrootUrl + L.Util.getParamString(parameters3);
var lyr_4 = new L.LayerGroup();
var ajax4 = $.ajax({
    url : URL3,
    dataType : 'jsonp',
    async: false,
    jsonpCallback : 'getJson',
    success : function (response) {
        console.log("Layer 4");
        L.geoJson(response, {
            style: function (feature) {
                return {
                    stroke: true,
                    color: getColor(feature.properties.luas_tanah),
                    opacity: 0.8,
                    weight: 1
                };
            },
            onEachFeature: function (feature, layer) {
                popupOptions = {maxWidth: 200};
                layer.bindPopup("<b>D NOP : </b> " + feature.properties.d_nop 
                    ,popupOptions);
            }
        }).addTo(lyr_4);
    },
    error: function (xhr, status) {
        alert("Failed call Layer D");
    }
});
var baseMaps = [
                {
                    groupName : "OSM Base Maps",
                    layers    : {
                        "OpenStreetMaps" : osmLayer
                    }
                }
        ];

var overlays = [
                {
                    groupName   : "Kecamatan",
                    expanded    : true,
                    layers      : {
                        "Layer A"     : lyr_1,
                        "Layer B"     : lyr_2,
                        "Layer C"     : lyr_3,
                        "Layer D"     : lyr_4
                    }   
                }
        ];
var options = {
            container_width     : "300px",
            group_maxHeight     : "800px",
            exclusive           : true
        };
var control = L.Control.styledLayerControl(baseMaps, overlays, options);
map.addControl(control);
var legend = L.control({position: 'bottomright'});
    legend.onAdd = function (map) {
        var div = L.DomUtil.create('div', 'info legend'),
            grades = [0, 100, 200, 500, 1000, 2000, 5000, 10000],
            labels = [],
            from, to;
        for (var i = 0; i < grades.length; i++) {
            from = grades[i];
            to = grades[i + 1];
            labels.push(
                '<i style="background:' + getColor(from + 1) + '"></i> ' +
                from + (to ? '&ndash;' + to : '+'));
        }
        div.innerHTML = labels.join('<br>');
        return div;
};
legend.addTo(map); 

});

现在我的问题是每次我打开页面一切都很好,但有时当我刷新页面时一切都崩溃了。例如,有时显示"层A"数据,有时数据最终出现在错误的数据集中。当我得到这个bug时,我在控制台中得到以下消息:

ows?service=WFS&version=1.0.0&request=GetFeature&typeName=pbb%3Aview_map&maxFeatures=1000&outputFor…:1 Uncaught TypeError: getJson is not a function

根据我的研究,在运行多个AJAX调用时,这种类型的错误似乎很常见。我不明白的是为什么这个错误不会100%发生。可以使用什么技术来修复它?我听说过deferred Objects,但无法将其应用到我的代码中,我在这方面的专业水平还远远不够。虽然这可能是一个GIS问题,但我相信这种类型的问题与普通的jQuery和异步调用更相关。

jsonpCallback Type: String or Function()
指定回调函数JSONP请求的名称。将使用此值代替由jQuery自动生成的随机名称。最好是让jQuery生成一个唯一的名称,因为它将使它更容易管理请求,并提供回调和错误处理。

不要用

删除这一行:

jsonpCallback : 'getJson',

当你同时有多个请求时,它们的回调函数(因为你强迫它们使用相同的名称)会相互覆盖


async: false

发出一个同步请求可以解决这个问题(因为你不能同时有多个同步请求在运行(它们排队)),但是它们是:

  • 太可怕了(它们在XHR中被主浏览器线程弃用是有充分理由的)
  • 与JSONP完全不兼容(所以你的指令被忽略)。

您也应该删除使请求同步的尝试

最新更新