使用openlayer getfeature 出现的跨域问题
很久没有更新了,事情很多,但是如果不每天写一写都不知道自己今天做了什么,肯定就是无所事事过去一天了。
废话少说。一直对前端很感兴趣。自己也是学GIS出身,为了今后能顺利一些毕业。就选了一些和gis相关的前端工具来研究。openlayers是一个很有效率的前端地图渲染js,源码已经在github上开放,fork一下就能下来,引用十分简单。
关于引用的一些注意的问题。
1.在调用geoserver的wms服务的时候,需要引用deprecated.js,主要需要创造一个容器。
2.geoserver发布服务就不多说了。我用的是处理过的shp,postgis也是很不错。记得找一个好一点的服务器,geoserver的效率还是没有某商业的server强悍。
跨域的问题描述
tiled = new OpenLayers.Layer.WMS(
"test:农华101_7月_平均气温平均shp - Tiled", "http://202.205.91.115:8080/geoserver/test/wms",
{
LAYERS: 'test:农华101_7月_平均气温平均shp',
STYLES: '',
format: format,
tiled: true,
tilesOrigin : map.maxExtent.left + ',' + map.maxExtent.bottom
},
{
buffer: 0,
displayOutsideMaxExtent: true,
isBaseLayer: true,
yx : {'EPSG:3752' : false}
}
);
这是我调用的一个已经发布好的wms,具体的参数就不说了。使用apache做web服务器,发布之后能正常显示地图,。
//注册一个click事件,点击查询图层属性数据
map.events.register(‘click’, map, function (e) {
document.getElementById('nodelist').innerHTML = "Loading... please wait...";
var params = {
REQUEST: "GetFeatureInfo",
EXCEPTIONS: "application/vnd.ogc.se_xml",
BBOX: map.getExtent().toBBOX(),
SERVICE: "WMS",
INFO_FORMAT: 'text/html',
QUERY_LAYERS: map.layers[0].params.LAYERS,
FEATURE_COUNT: 50,
Layers: 'test:农华101_7月_平均气温平均shp',
WIDTH: map.size.w,
HEIGHT: map.size.h,
format: format,
styles: map.layers[0].params.STYLES,
srs: map.layers[0].params.SRS};
//如果不加入deprecated.js,loadURL这个方法会提示没有定义
OpenLayers.loadURL("http://202.205.91.115:8080/geoserver/test/wms", params, this, setHTML, setHTML);
OpenLayers.Event.stop(e);
getfeatrueinfo这个方法怎么也无法获取到数据,google之后发现原来使用xml数据,因为web服务和地图服务分别使用80和8080两个端口,发生跨域问题,而浏览器是不支持跨域(chrome ff ie8+ safari)
解决办法
原理 openlayers提供了跨域的脚本。不过是python写的,保证服务器安装了python。复制如下代码存下放到网站的根目录
#!/usr/bin/env python // 这是linux的你安装的python路径,如果是win的服务器,应该是路径/python.exe -u这样。
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','你的server地址+端口']
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 = "你的server地址+端口"
else:
fs = cgi.FieldStorage()
url = fs.getvalue('url', "你的server地址+端口g")
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
或者把openlayers文件夹下exampels的proxy.cgi文件按照上面的改法改下放入网站根目录。
然后在前台调用init函数加入声明
OpenLayers.ProxyHost = 'proxy.cgi?url=';
最后再把apache里面配置下能跑得起来python就可以。