浅析使用代理解决WFS服务跨域的问题

作者:Lily

       在项目开发中,使用WFS数据服务做一些数据方面的操作的时候,经常会遇到跨域的问题,那么今天我就给大家介绍一下如何通过代理来解决WFS跨域的问题。
下面是我们在前端对WFS服务做操作的时候常遇到的问题:

XMLHttpRequest cannot load 
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:xxxx' is therefore not allowed access.

很显然这是跨域的问题,那么我先简单的介绍一下什么是跨域,跨域就是因为JavaScript同源策略的限制,通俗的说就是一个站点中的资源去访问另外一个不同域名站点上的资源,比如说通过 style 标签加载外部样式表文件、通过 img 标签加载外部图片、通过 script 标签加载外部脚本文件、通过 Webfont 加载字体文件等等。同源策略如下:
这里写图片描述
遇到跨域问题一般都有多种解决方案,既然本文用代理解决,我也就说一下什么是代理。代理,通俗的讲就是一个传递媒介,它将客户端向服务器发送的请求进行传递和处理。一个完整的代理请求过程为:
    1)客户端把向服务器发送的请求交给代理; 2) 代理接收并处理请求;3)代理将请求发送到服务器;4)服务器接收请求并将结果返回给代理;5)代理再将结果返回给客户端。

下面我以一个案例的形式帮助大家理解到底如何使用代理解决跨域问题:
    首先,创建一个工程项目,该项目的目的是使用WFS服务做一个几何查询服务,并将查询结果在前端渲染显示,这里将这个项目命名为ky,新建一个html文件同样命名为ky,将所要实现的功能写进这个html里面,这时候在浏览器中访问这个html页面做查询操作,如下图,没有返回结果:
这里写图片描述
并且浏览器会报跨域的错误。例如本例的:

XMLHttpRequest cannot load 
http://192.168.15.99:8090/iserver/services/data-world/wfs100. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.

那么如何解决呢,请看下面的操作步骤:
1、将工程文件夹(如本例ky)拷贝到iserver的webapps这个目录下。
2、将代理文件放在iserver webapps里的工程目录下,这个代理文件可以根据自己项目情况写一个,也可以在网上下载,下面是本例中用到的一个代理jsp文件(注:supermap iserver服务器中自带的有这个文件,文件位置为iserver解压包里的iClient\forJavaScript\examples目录下)。jsp的处理过程为:
       1) 接收客户端请求传递的参数 2) 将参数重新组合 3) 通过java.net.URL构造构造新的HTTP请求 4) 读取请求返回的内容 5) 组合返回的内容再发回给客户端。
下面是实现的代码:

<%@page session="false"%>
<%@page import="java.net.*,java.io.*" %>
<%@ page pageEncoding="UTF-8" isELIgnored="false" %>
<%
try {
	String reqUrl = request.getParameter("url");
	
	URL url = new URL(reqUrl);
	HttpURLConnection con = (HttpURLConnection)url.openConnection();
	con.setRequestProperty("content-type", "application/xml; charset=UTF-8");
	con.setDoOutput(true);
	con.setRequestMethod(request.getMethod());
	//con.setCharacterEncoding("UTF-8");  
	int clength = request.getContentLength();
	if(clength > 0) {
		con.setDoInput(true);
		byte[] idata = new byte[clength];
		
		//String s = String.ValueOf(clength);
		//System.out.println(clength);
		
		BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream)request.getInputStream()));  
		String line1 = null;  
		StringBuilder sb = new StringBuilder();  
		while((line1 = br.readLine())!=null){  
		   sb.append(line1);  
		}
		//request.getInputStream().read(idata, 0, clength);
		//String test=String.valueOf(idata);
		//System.out.println(sb);
		
		//OutputStreamWriter out=new OutputStreamWriter(con.getOutputStream()); 
		//out.write(new String(sb.toString().getBytes("ISO-8859-1")));

		byte[] paradata = sb.toString().getBytes();
		con.getOutputStream().write(paradata);
	}
	response.setContentType(con.getContentType());

	BufferedReader rd = new BufferedReader(new InputStreamReader(con.getInputStream(),"UTF-8"));
	String line;
	StringBuilder sb1 = new StringBuilder();  
	while ((line = rd.readLine()) != null) {
		out.println(line); 	
		sb1.append(line);  	
	}
	rd.close();

} catch(Exception e) {
System.out.println(0);
System.out.println(e);

	response.setStatus(500);
}
%>

3、 发送代理请求,按照这样的请求格式:SuperMap.ProxyHost= "项目地址/Proxy.jsp?url=",注意url参数中特殊字符需要转码。将这段代码写入项目中能够访问到的位置
例如本例中我是将" SuperMap.ProxyHost= http://localhost:8090/ky/Proxy.jsp?url=”这段代码放在init()这个方法里面
4、 最后通过IP加端口号的形式访问发布后的项目就不会出现跨域的问题了,下图为查询成功所返回的结果:
这里写图片描述

以下链接是我对这个方法测试的一个例子,供大家参考,系统是发布在我本地的,WFS服务是在另外一台服务器上,在项目中代理请求的位置在ky.html的第123行:
http://download.csdn.net/detail/supermapsupport/9743816

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Geoserver是一个开源的地理信息系统服务器,它能够将空间数据(如地图、矢量数据等)按照标准的协议(如WMS、WFS等)发布到互联网上,以便于其他应用程序进行访问和使用。但是,在开发过程中,我们可能会遇到geoserver跨域问题,这会影响到应用程序的正常运行。 所谓跨域,指的是在浏览器中,访问一个与当前页面不同域名的资源。例如,在本地部署了一个geoserver服务,在前端页面中使用ajax请求geoserver的数据时,就会出现跨域问题。为了解决这个问题,需要在geoserver的配置文件中进行相关设置。 我们可以通过修改geoserver的web.xml配置文件来解决跨域问题,具体方法如下: 1.找到geoserver的安装目录下webapps/geoserver/WEB-INF目录下的web.xml文件。 2.在文件末尾加入以下内容: <filter> <filter-name>CorsFilter</filter-name> <filter-class>org.eclipse.jetty.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, HEAD, OPTIONS</param-value> </init-param> <init-param> <param-name>allowedHeaders</param-name> <param-value>origin, content-type, accept</param-value> </init-param> </filter> <filter-mapping> <filter-name>CorsFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 3.保存文件,并重启geoserver。 上述设置会开启一个CorsFilter过滤器,该过滤器能够将来自所有域名的请求都允许通过,从而解决geoserver跨域问题。 总之,geoserver跨域问题虽然会影响到应用程序的正常运行,但是通过修改geoserver的web.xml配置文件,我们可以轻松解决这个问题,确保应用程序的顺利运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值