java跨域解决思路及实现原理二

我的上一篇文章讲了前端跨域的解决方案,这篇文章要讲的是java服务器端解决跨域。


先介绍一种最简单的解决方案:


springMVC的框架在4.2以上的版本就可以使用注解来实现跨域。我们并不需要去关注什么原理,直接拿来用就可以。
在我们的controller文件上添加@CrossOrigin注解,那么这个文件下的请求都支持跨域。如果要控制到某个请求被支持跨域,那么只要为该请求单独加上@CrossOrigin注解即可。
在@CrossOrigin注解里有一个叫“origins”的参数,设置这个参数就可以允许指定的服务器跨域。比如: @CrossOrigin(origins = "*")这样就表示允许所有跨域访问。


这里我仔细的讲一下,对于跨域其实就是修改了请求报头。下面的一些方法就是通过修改response的头文件来达到跨域效果。而@CrossOrigin注解也是去修改response的头文件来实现的。


有可能对于跨域上一篇的文章讲的还不是很清楚。我再重复一遍:跨域并非浏览器限制了发起跨站请求,而是跨站请求可以正常发起,但是返回结果被浏览器拦截了。理解这一点是很重要的。


在开始下面的方法讲解之前了解一下response的头文件:
Access-Control-Allow-Origin:| * // 授权的源控制
Access-Control-Max-Age:// 授权的时间
Access-Control-Allow-Credentials: true | false // 控制是否开启与Ajax的Cookie提交方式
Access-Control-Allow-Methods:[,]* // 允许请求的HTTP Method
Access-Control-Allow-Headers:[,]* // 控制哪些header能发送真正的请求


注解以外的解决方案:


通过上面的讲解我们不难发现,所谓解决跨域就是要解决数据如何能够正确返回。这里我提供两种思路:一、继承的方式;二、拦截器的方式。


这里我比较推荐拦截器的方式,因为它不需要修改每个controller类。下面来看一下实现:
首先需要新建一个拦截器类,然后设置ressponse的头文件。下面来看具体代码:
public void doFilter(ServletRequest request, ServletResponse servletResponse,
            FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS,DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Authorization");
response.setHeader("Access-Control-Allow-Credentials","true");
chain.doFilter(request, servletResponse);
}


拦截器实现了之后就需要在web.xml中配置,使拦截器发挥效果。下面是web.xml中的代码:
<filter>
     <filter-name>cors</filter-name>
     <filter-class>xxx.xxxx.HeadersCORSFilter</filter-class><!--过滤器路径-->
</filter>
<filter-mapping>
     <filter-name>cors</filter-name>
     <url-pattern>/url/*</url-pattern><!--接口前缀-->
</filter-mapping>


到这里使用拦截器的解决方案就完成了。至于继承的方式就是写一个公共的controller类,在该类中实现跨域,然后需要跨域的controller类继承该类就可以实现跨域了。


最后我再拓展一下浏览器cookie跨域。由于项目的原因,我的每次请求后台都会查看当前的cookie,如果没有登录成功时后台设置的cookie将会被拒绝访问。这样会带来一个问题,在另开页面访问时cookie无法共享导致请求失败。决解方法很简单就是在ajax请求时给xhrFields属性设置{ withCredentials: true }。完整的ajax请求代码展示:
$.ajax({
type:"post",
url:"url",
async:true,
xhrFields: { withCredentials: true },
data:,
dataType: "json",
success: function(result) {},
error: function(ret) {}
});


关于跨域的问题就讲这么多,谢谢。

猜你喜欢

转载自blog.csdn.net/hpljava/article/details/78548838
今日推荐