[GIS] ‘Access-Control-Allow-Origin’ error in defining wfs layer in OpenLayers 3

openlayerswfs

I want to create a wfs layer in OpenLayers 3. I define it as follow:

sourceVector = new ol.source.Vector({
    loader: function(extent) {
        $.ajax('http://localhost:8080/geoserver/iran/wfs?service=WFS',{
            type: 'GET',
            data: {
                service: 'WFS',
                version: '1.1.0',
                request: 'GetFeature',
                typename: 'iran:capital',
                srsname: 'EPSG:4326',
                bbox: extent.join(',') + ',EPSG:4326'
                },
            }).done(loadFeatures);
        },
        strategy: ol.loadingstrategy.tile(new ol.tilegrid.XYZ({
            maxZoom: 19
            })),
    });

window.loadFeatures = function(response) {
    formatWFS = new ol.format.WFS(),
    sourceVector.addFeatures(formatWFS.readFeatures(response));
    };

wfs = new ol.layer.Vector({
    source: sourceVector,
    style: new ol.style.Style({
        stroke: new ol.style.Stroke({
            color: 'rgba(0, 0, 255, 1.0)',
            width: 2
        })
    })
});

But when I run the project, I'm faced with this error:

XMLHttpRequest cannot load
http://localhost:8080/geoserver/iran/wfs?service=WFS&service=WFS&version=1.…3702828511596%2C0%2C6.02966565566021e-11%2C76.43702828517625%2CEPSG%3A4326.
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost' is therefore not allowed access.
enter image description here

this problem was in OpenLayers 2, but I solved it as follow:

I created a proxy.cgi file with the following values:

#!C:/Python27/python.exe -u

"""This is a blind proxy that we use to get around browser
restrictions that prevent the Javascript from loading pages not on the
same server as the Javascript.  This has several problems: it's less
efficient, it might break some sites, and it's a security risk because
people can use this proxy to browse the web and possibly do bad stuff
with it.  It only loads pages via http and https, but it can load any
content type. It supports GET and POST requests."""

import urllib2
import cgi
import sys, os

# Designed to prevent Open Proxy type stuff.

allowedHosts = ['www.openlayers.org', 'openlayers.org', 
                'labs.metacarta.com', 'world.freemap.in', 
                'prototype.openmnnd.org', 'geo.openplans.org',
                'sigma.openplans.org', 'demo.opengeo.org',
                'www.openstreetmap.org', 'sample.azavea.com',
                'v2.suite.opengeo.org', 'v-swe.uni-muenster.de:8080',
                'vmap0.tiles.osgeo.org', 'www.openrouteservice.org',
                'maps.wien.gv.at', 'localhost:8080']

method = os.environ["REQUEST_METHOD"]

if method == "POST":
    qs = os.environ["QUERY_STRING"]
    d = cgi.parse_qs(qs)
    if d.has_key("url"):
        url = d["url"][0]
    else:
        url = "http://www.openlayers.org"
else:
    fs = cgi.FieldStorage()
    url = fs.getvalue('url', "http://www.openlayers.org")

try:
    host = url.split("/")[2]
    if allowedHosts and not host in allowedHosts:
        print "Status: 502 Bad Gateway"
        print "Content-Type: text/plain"
        print
        print "This proxy does not allow you to access that location (%s)." % (host,)
        print
        print os.environ

    elif url.startswith("http://") or url.startswith("https://"):

        if method == "POST":
            length = int(os.environ["CONTENT_LENGTH"])
            headers = {"Content-Type": os.environ["CONTENT_TYPE"]}
            body = sys.stdin.read(length)
            r = urllib2.Request(url, body, headers)
            y = urllib2.urlopen(r)
        else:
            y = urllib2.urlopen(url)

        # print content type header
        i = y.info()
        if i.has_key("Content-Type"):
            print "Content-Type: %s" % (i["Content-Type"])
        else:
            print "Content-Type: text/plain"
        print

        print y.read()

        y.close()
    else:
        print "Content-Type: text/plain"
        print
        print "Illegal request."

except Exception, E:
    print "Status: 500 Unexpected Error"
    print "Content-Type: text/plain"
    print 
    print "Some unexpected error occurred. Error text was:", E

and then I set OpenLayers.proxyHost to OpenLayers.ProxyHost = "proxy.cgi?url";

How can I do in OpenLayers 3 for this problem(I use Apachea in server side)?

Best Answer

You could enable CORS on the Apache Server. In practice this is faster than using a ProxyPass. Enabling a Catalina filter on Apache Tomcat is very simple. Including restart this should be done in 2 minutes.

Here is a link for enabling CORS on Apache Tomcat.

I used the same article to enable CORS on my own dev Geoserver hosted on Openshift.