java web项目使用CORS方法实现跨域请求方案

来源:互联网 发布:海口网站快速优化排名 编辑:程序博客网 时间:2024/04/30 14:39

问题产生背景

需要实现这样一个需求,在当前站点中使用ajax发送一个请求到另一个站点获取数据。js中使用jquery的ajax如下:

1234567891011
$.ajax({     url:http://219.151.48.39:8085/kanms_appServer/operationer/login,     data:{     "username": "test","password": "test"      },     type:'post',     dataType:'json',     success:function(data){     console.info(data);                });

结果在页面上出现以下错误提示:

123
XMLHttpRequest cannot load http://219.151.48.39:8085/kanms_appServer/operationer/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

问题分析

网上查询得知原来是因为跨域的问题,javascript出于安全方面的考虑,不允许跨域调用其他页面的对象。

什么是跨域?
简单的理解就是因为javascript同源策略的限制,a.com域名下的js无法操作b.com或者c.a.com域名下的对象。更详细的说明可以看下表:

URL说明是否允许通信http://www.a.com/a.js 
http://www.a.com/b.js同一域名下允许http://www.a.com/lab/a.js 
http://www.a.com/script/b.js同一域名下不同文件夹允许http://www.a.com:8000/a.js 
http://www.a.com/b.js同一域名不同端口不允许http://www.a.com/a.js 
https://www.a.com/b.js同一域名不同协议不允许http://www.a.com/a.js 
http://70.32.92.74/b.js域名和域名对应ip不允许http://www.a.com/a.js 
http://script.a.com/b.js主域相同,子域不同不允许http://www.a.com/a.js 
http://a.com/b.js同一域名,不同二级域名(同上)不允许(cookie这种情况下也允许访问)http://www.cnblogs.com/a.js 
http://www.a.com/b.js不同域名不允许

经分析得知js中XMLHttpRequest对象不能加载跨域上的资源

解决办法

那么,怎样才能解决跨域访问资源的问题呢,主要有JSONPflashiframexhr2。这里介绍使用CORS(跨域资源共享,Cross-Origin Resource Sharing)的方法。

CORS原理:
CORS定义一种跨域访问的机制,可以让AJAX实现跨域访问。CORS 允许一个域上的网络应用向另一个域提交跨域 AJAX 请求。实现此功能非常简单,只需由服务器发送一个响应标头即可。

做法为:设置HTTP响应头Access-Control-Allow-Origin,指定服务器端允许进行跨域资源访问的来源域。可以用通配符*表示允许任何域的JavaScript访问资源,但是在响应一个携带身份信息(Credential)的HTTP请求时,Access-Control-Allow-Origin必需指定具体的域,不能用通配符。

这里使用Filter的方式给服务端的所有请求都加上Access-Control-Allow-Origin响应头,代码如下:

SimpleCORSFilter类

123456789101112131415161718192021222324252627282930313233343536
package com.ustcinfo.kanms.support;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletResponse;public class SimpleCORSFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {HttpServletResponse res = (HttpServletResponse)response;res.setHeader("Access-Control-Allow-Origin", "*");res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");res.setHeader("Access-Control-Max-Age", "3600");res.setHeader("Access-Control-Allow-Headers", "x-requested-with");chain.doFilter(request, response);}@Overridepublic void destroy() {}}

web.xml中添加过滤器的配置

123456789
<!-- cors解决跨域访问问题 --><filter><filter-name>cors</filter-name><filter-class>com.ustcinfo.kanms.support.SimpleCORSFilter</filter-class></filter><filter-mapping><filter-name>cors</filter-name><url-pattern>/*</url-pattern></filter-mapping>

加上以上代码后,使用原来的ajax访问跨域服务端信息的Response Header如下:

1234567
Access-Control-Allow-Headers:x-requested-withAccess-Control-Allow-Methods:POST, GET, OPTIONS, DELETEAccess-Control-Allow-Origin:*Access-Control-Max-Age:3600Content-Type:application/json;charset=UTF-8Server:Jetty(8.1.10.v20130312)Transfer-Encoding:chunked

并且可以通过ajax访问跨域服务器的资源了,大功告成。


原创粉丝点击