Getting WFS data from Geoserver into leaflet

While you can set up a proxy with your webserver, there is an easier way.

First, enable JSONP in GeoServer.

Then form your data requests like this:

var owsrootUrl = 'https://<GEOSERVER URL - CHANGEME>/geoserver/ows';

var defaultParameters = {
    service : 'WFS',
    version : '2.0',
    request : 'GetFeature',
    typeName : '<WORKSPACE:LAYERNAME - CHANGEME>',
    outputFormat : 'text/javascript',
    format_options : 'callback:getJson',
    SrsName : 'EPSG:4326'
};

var parameters = L.Util.extend(defaultParameters);
var URL = owsrootUrl + L.Util.getParamString(parameters);

var WFSLayer = null;
var ajax = $.ajax({
    url : URL,
    dataType : 'jsonp',
    jsonpCallback : 'getJson',
    success : function (response) {
        WFSLayer = L.geoJson(response, {
            style: function (feature) {
                return {
                    stroke: false,
                    fillColor: 'FFFFFF',
                    fillOpacity: 0
                };
            },
            onEachFeature: function (feature, layer) {
                popupOptions = {maxWidth: 200};
                layer.bindPopup("Popup text, access attributes with feature.properties.ATTRIBUTE_NAME"
                    ,popupOptions);
            }
        }).addTo(map);
    }
});

This has the additional advantage on working on your test server, as it avoids cross site scripting issues due to the use of JSONP (quoted json objects, from my understanding).

For an example of this in action, see these two maps:

  • https://maps.gcc.tas.gov.au/glenorchy_mtbp.html
  • https://maps.gcc.tas.gov.au/stormwater.html

Code here (for posterity).

By the way, I use nginx for the webserver and have the proxy stuff working. If you would like to know how please let me know and I'll edit something in here.

EDIT: another way of getting rid of this error is enabling CORS in either Tomcat (or Jetty, maybe?) or your reverse proxy.


Regardless of the library used, web browsers won't allow loading Ajax content from another port (in this case 8080), even from the same domain. The easiest way to fix this is to set up mod_proxy in Apache webserver (sample configuration: mod_proxy geoserver Gist), which allows to redirect all GeoServer-related traffic to port 80 and thus no Access-Control-Allow-Origin restrictions will apply.


I'm not sure this is the appropriate answer, but I wanted to point out that setting up the proxying in nginx is very easy.

Let's say Geoserver is running on port 8080, and your web server (nginx) is running on port 80. It's as simple as adding:

location /geoserver {
   proxy_set_header Host $http_host;
   proxy_pass http://127.0.0.1:8080;
}

to your /etc/nginx/sites-enabled/default (or whatever). Now you can send your JSON calls to port 80, and experience no more cross-origin scripting issues.

It would be much trickier if geoserver didn't conveniently have a URL structure which begins "/geoserver".

(It's a personal question whether configuring Nginx or modifying your Javascript is "easier"... This arrangement also means one less port that needs to be opened in your firewall.)