文章转载出处:[Openlayers WFS跨域请求](http://blog.csdn.net/freeland1/article/details/41204485)
通常web项目于gis服务器不在同一域下,这就涉及到了wfs跨域问题。
1 c#代理
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net;
using System.IO;
namespace WebApplication1
{
/// <summary>
/// OpenlayerProxy 的摘要说明
/// </summary>
public class OpenlayerProxy : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
if (string.IsNullOrEmpty(context.Request["URL"])) return;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(context.Request["URL"]);
request.UserAgent = context.Request.UserAgent;
request.ContentType = context.Request.ContentType;
request.Method = context.Request.HttpMethod;
byte[] trans = new byte[1024];
int offset = 0;
int offcnt = 0;
if (request.Method.ToUpper() == "POST")
{
Stream nstream = request.GetRequestStream();
while (offset < context.Request.ContentLength)
{
offcnt = context.Request.InputStream.Read(trans, offset, 1024);
if (offcnt > 0)
{
nstream.Write(trans, 0, offcnt);
offset += offcnt;
}
}
nstream.Close();
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
//Encoding enc = Encoding.GetEncoding(65001);
context.Response.ContentType = response.ContentType;
StreamReader loResponseStream = new StreamReader(response.GetResponseStream());
string lcHtml = loResponseStream.ReadToEnd();
context.Response.Write(lcHtml);
response.Close();
loResponseStream.Close();
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
2 基于java的servlet
package com.nkstar.action;
import javax.servlet.http.HttpServlet;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* This is a transparent HTTP proxy written in Java that is similar to the proxy
* in the OpenLayers examples, which is written in Python. These proxies are
* used to circumvent browser restrictions on cross-domain requests with
* Javascript.
* </p>
* <p>
* To use the proxy you need to 1) configure the proxy servlet in your web.xml
* and 2) use OpenLayers.setProxyHost to set the url-path to the proxy. If the
* proxy is configured to listen to the url-pattern '/gwtOpenLayersProxy/*' then
* the proxy host should be set to 'gwtOpenLayersProxy?targetURL='.
* </p>
* Initial code for this proxy is based upon <a href=
* "http://trac.openlayers.org/changeset/8099/sandbox?format=diff&new=8099">the
* following code</a><br />
* see also <a href=
* "http://java.sun.com/docs/books/tutorial/networking/urls/readingWriting.html"
* title="this networking tutorial">this networking tutorial</a>
* <p>
*/
@SuppressWarnings("serial")
public class OpenLayersProxyServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
processRequest(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
processRequest(request, response);
}
private void processRequest(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
HttpURLConnection connection = null;
InputStream istream = null; // input to proxy
OutputStream ostream = null; // output from proxy
InputStream connectionIstream = null; // output for the target is
// input for the connection
OutputStream connectionOstream = null; // input for the target is
// output for the connection
String remoteHost = request.getRemoteHost(); // get host address of
// client - for checking
// allowedHosts
boolean allowedHost = isAllowedHost(remoteHost); // The allowedHosts
// are the hosts
// that are allowed
// to use the Open
// Proxy.
try {
// easy way to ignore case of param?
if (request.getParameter("targetURL") != null
&& request.getParameter("targetURL") != "" && allowedHost) {
// HTTPUrlConnection looks at http.proxyHost and http.proxyPort
// system properties.
// Make sure these properties are set these if you are behind a
// proxy.
// step 1: initialize
String requestMethod = request.getMethod();
URL targetURL = new URL(request.getParameter("targetURL"));
connection = (HttpURLConnection) targetURL.openConnection();
connection.setRequestMethod(requestMethod);
transferHTTPRequestHeaders(connection, request);
// step 2: proxy requests
if (requestMethod.equals("GET")) {
// default for setDoInput is true
connectionIstream = connection.getInputStream();
}
;
if (requestMethod.equals("POST")) {
transferHTTPRequestHeadersForPOST(connection, request);
int clength = request.getContentLength();// clength is
// for checking
// if there is a
// POST body. Is
// that
// sufficient?
if (clength > 0) {
istream = request.getInputStream();
connection.setDoOutput(true);// for POST we need to
// write to connection
connection.setRequestProperty("Content-Length", Integer
.toString(clength)); // only valid for POST
// request
connectionOstream = connection.getOutputStream();
// copy the request body to remote outputStream
copy(istream, connectionOstream);
}
connectionIstream = connection.getInputStream();
}
// step 3: return output
// can output be the same for GET/POST? or different return
// headers?
// servlet may return 3 things: status code, response headers,
// response body
// status code and headers have to be set before response body
response.setContentType(connection.getContentType());
ostream = response.getOutputStream();
copy(connectionIstream, ostream);
}
// if not targetURL send page that targetURL is required param
} catch (Exception e) {
response.setStatus(500); // what will user get? default page for
// response code
// WMS/WFS have specific responses to errors
// response.getWriter();//will writing custom result help
e.printStackTrace();
} finally {
if (istream != null) {
istream.close();
}
if (ostream != null) {
ostream.close();
}
if (connectionIstream != null) {
connectionIstream.close();
}
if (connectionOstream != null) {
connectionOstream.close();
}
}
}
private void copy(InputStream istream, OutputStream ostream)
throws Exception {
int bufferSize = 4 * 4 * 1024;// same buffer size as in Jetty utils
// (2*8192)
byte[] buffer = new byte[bufferSize];
int read;
while ((read = istream.read(buffer)) != -1) {
ostream.write(buffer, 0, read);
}
}
private void transferHTTPRequestHeaders(HttpURLConnection connection,
HttpServletRequest request) {
// TODO make sure all headers are copied to target, see for HTTP headers
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
// Do request.getProperties to get request properties
if (request.getHeader("Accept") != null) {
connection
.setRequestProperty("Accept", request.getHeader("Accept"));
}
if (request.getHeader("Accept-Charset") != null) {
connection.setRequestProperty("Accept-Charset", request
.getHeader("Accept-Charset"));
}
if (request.getHeader("Accept-Encoding") != null) {
// TODO browsers accept gzipped, should proxy accept gzip and how to
// handle it?
// connection.setRequestProperty("Accept-Encoding",
// request.getHeader("Accept-Encoding"));
}
if (request.getHeader("Authorization") != null) {
connection.setRequestProperty("Authorization", request
.getHeader("Authorization"));
}
if (request.getHeader("Connection") != null) {
// TODO HTTP/1.1 proxies MUST parse the Connection header field
// before a message is forwarded and, for each connection-token in
// this field, remove any header field(s) from the message with the
// same name as the connection-token.
// connection.setRequestProperty("Connection",
// request.getHeader("Connection"));
}
// set de-facto standard proxy headers (x-forwarded-for, others?s)
if (request.getHeader("X-Forwarded-For") != null) {
connection.setRequestProperty("X-Forwarded-For", request
.getHeader("X-Forwarded-For"));// TODO append IP proxy
} else {
connection.setRequestProperty("X-Forwarded-For", request
.getRemoteAddr());// TODO append IP proxy
}
}
private void transferHTTPRequestHeadersForPOST(
HttpURLConnection connection, HttpServletRequest request) {
if (request.getHeader("Content-Type") != null) {
connection.setRequestProperty("Content-Type", request
.getContentType());
} else {
// throw exception?
}
}
private boolean isAllowedHost(String remoteHost) {
// TODO checking of host
return true;
}
}
ashx,servlet这两种直接可以放在web项目当中部署,简单操作。 使用说明
OpenLayer2代理使用,只需在程序开头或init方法第一句写上proxyhost即可。
[javascript]
view plain
copy
print
?
OpenLayers.ProxyHost =
‘/OpenlayerProxy.ashx?URL=’;
var url =
‘http://localhost:8090/geoserver/wfs?SERVICE=WFS&VERSION=1.1.0&REQUEST=GetFeature&OUTPUTFORMAT=GML2&TYPENAME=pgrouting:Mypgrouting&viewparams=’ + viewparams;
var request = OpenLayers.Request.POST({ url: url, callback: onComplete });
OpenLayer3 代理使用
[javascript]
view plain
copy
print
?
queryButton.addEventListener(
‘click’,
function (event) {
var viewparams =
“ARRAY[[“ + locatearr.join(
“],[“) +
“]]”; viewparams = stringReg(viewparams); viewparams =
”destinationarr:” + viewparams;
var url =
‘http://localhost:8090/geoserver/wfs?SERVICE=WFS&VERSION=1.1.0&REQUEST=GetFeature&OUTPUTFORMAT=json&TYPENAME=pgrouting:Mypgrouting&viewparams=’ + viewparams; url =
’/OpenlayerProxy.ashx?URL=’ + encodeURIComponent(url); $.ajax({ type:
”POST”, url: url, dataType:
”text”, success: onComplete }); });
需要对url进行编码,否则代理进去丢失参数。
3 使用cros
3.1 下载地址:http://pan.baidu.com/s/1miDDwJu
3.2 下载后解压,得到的是org/mortbay/servlets/CrossOriginFilter.class文件,把此文件复制到安装目录下的WEB-INF/classes文件夹中,在我电脑上的路径为:GeoServer 2.7.0\webapps\geoserver\WEB-INF\classes\org\mortbay\servlets\CrossOriginFilter.class.
3.3 打开geoserver安装目录下的web.xml文件,我的电脑上路径为:GeoServer 2.7.0\webapps\geoserver\WEB-INF\web.xml
3.4 在filter集合末尾额外添加一个filter:
<filter> <filter-name>cross-origin</filter-name> <filter-class>org.mortbay.servlets.CrossOriginFilter</filter-class> <init-param> <param-name>allowedOrigins</param-name> <param-value>*</param-value> </init-param> <init-param> <param-name>allowedMethods</param-name> <param-value>GET,POST</param-value> </init-param> <init-param> <param-name>allowedHeaders</param-name> <param-value>X-Requested-With,Content-Type,Accept,Origin</param-value> </init-param> </filter>
3.5 在filter-mapping末尾额外添加一个filter-mapping
<filter-mapping> <filter-name>cross-origin</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
3.6 重启GeoServer服务即可。
优点:post,get跨域请求即可。
–以上针对geoserver2.9以下版本,以独立安装方式,非war包形式安装。
–以下针对>=geoserver2.9版本设置如下:
1 从http://central.maven.org/maven2/org/eclipse/jetty/jetty-servlets/下载对应的jar,比如geoserver2.9依赖的jetty版本号是9.2.13.v20150730,那么就下载该版本的jar。
2 将下载好的
jetty-servlets-9.2.13.v20150730.jar
放到webapps/geoserver下的lib中。
3 配置下webapps/geoserver/web.xml。
<filter> <filter-name>cross-origin</filter-name> <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class> </filter> <filter-mapping> <filter-name>cross-origin</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
4 重启geoserver即可。
4 使用jsonp
4.1 打开geoserver安装目录下的web.xml文件,我的电脑上路径为:GeoServer 2.7.0\webapps\geoserver\WEB-INF\web.xml
4.2 将jsonp注释取消
4.3 重启GeoServer。
4.4 使用示例
[javascript]
view plain
copy
print
?
function getFeature(options) { $.ajax(Global360Val.gisserverhost+
’geoserver/wfs’,{ type:
’GET’, data: { service:
’WFS’, version:
’1.1.0’, request:
’GetFeature’, typename: options.typename, srsname: options.srid, outputFormat:
’text/javascript’, viewparams:options.viewparams, bbox:(options.extent===undefined)?undefined:options.extent.join(
’,’) +
‘,’+options.srid, filter:options.filter }, dataType:
’jsonp’, jsonpCallback:
’callback:’+options.callback, jsonp:
’format_options’ }); }
[javascript]
view plain
copy
print
?
Source.deviceSource=
new ol.source.Vector(); getFeature({ typename:
’tb_place_management’, callback:
’loadDevice’ });
function loadDevice(res){
var features=geojsonFormat.readFeatures(res); Source.deviceSource.addFeatures(features); }
优点:无需安装插件,取消注释即可。
缺点:jsonb只能get,对于参数过长的url的get会失败。不能post,所以提交xml,或者wfs_t都不行。
完毕!
转载请注明原文地址: https://ju.6miu.com/read-34422.html