Java实现CORS跨域请求的实现方法

作者:关注kMacro 时间:2022-04-01 19:49:18 

问题

使用前后端分离模式开发项目时,往往会遇到这样一个问题 -- 无法跨域获取服务端数据

这是由于浏览器的同源策略导致的,目的是为了安全。在前后端分离开发模式备受青睐的今天,前端和后台项目往往会在不同的环境下进行开发,这时就会出现跨域请求数据的需求,目前的解决方案主要有以下几种:

JSONP、iframe、代理模式、CORS等等
前面几种方式在这里不讲,网上有很多资料。在这里我主要分享一下CORS这种解决方式,CORS即“跨域资源共享”,它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

使用 CORS 跨域的时候和普通的 ajax 过程是一样的,只是浏览器在发现这是一个跨域请求的时候会自动帮我们处理一些事情,所以说只要服务端提供支持,前端是不需要做额外的事情的。

实现

实现的大概思路是这样的,首先使用过滤器获取请求对象request的信息,比如Origin 字段(表示请求来自哪个源,包括协议、域名、端口),通过预先配置的参数判断请求是否合法,然后设置响应对象response的头信息,实现跨域资源请求。在介绍实现方式之前我们先来了解一下会用到的响应头信息。

响应头

Access-Control-Allow-Methods
用来列出浏览器的CORS请求允许使用的HTTP方法,如:GET、POST、PUT、DELETE、OPTIONS

Access-Control-Allow-Credentials
表示是否支持跨域Cookie

Access-Control-Allow-Headers
逗号分隔的字符串,表示服务器支持的所有头信息字段,如Content-Type以及自定义的字段

Access-Control-Expose-Headers
与“Access-Control-Allow-Headers”相反,表示不支持的头信息字段

Access-Control-Allow-Origin
允许跨域的请求源信息,包括协议、域名、端口,为*表示允许所有请求来源,并且只能设置一个请求源

下面介绍一下Java后台如何实现这种方式。

代码

由于最近在使用spring-boot,所以接下来以spring-boot为基础来实现。

首先创建一个CorsFilter过滤器,代码如下:


...
@WebFilter(filterName = "corsFilter", urlPatterns = "/*",
   initParams = {@WebInitParam(name = "allowOrigin", value = "*"),
       @WebInitParam(name = "allowMethods", value = "GET,POST,PUT,DELETE,OPTIONS"),
       @WebInitParam(name = "allowCredentials", value = "true"),
       @WebInitParam(name = "allowHeaders", value = "Content-Type,X-Token")})
public class CorsFilter implements Filter {

private String allowOrigin;
 private String allowMethods;
 private String allowCredentials;
 private String allowHeaders;
 private String exposeHeaders;

@Override
 public void init(FilterConfig filterConfig) throws ServletException {
   allowOrigin = filterConfig.getInitParameter("allowOrigin");
   allowMethods = filterConfig.getInitParameter("allowMethods");
   allowCredentials = filterConfig.getInitParameter("allowCredentials");
   allowHeaders = filterConfig.getInitParameter("allowHeaders");
   exposeHeaders = filterConfig.getInitParameter("exposeHeaders");
 }

@Override
 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
   HttpServletRequest request = (HttpServletRequest) servletRequest;
   HttpServletResponse response = (HttpServletResponse) servletResponse;
   if (!StringUtils.isEmpty(allowOrigin)) {
     if(allowOrigin.equals("*")){
       response.setHeader("Access-Control-Allow-Origin", allowOrigin);
     }else{
       List<String> allowOriginList = Arrays.asList(allowOrigin.split(","));
       if (allowOriginList != null && allowOriginList.size() > 0) {
         String currentOrigin = request.getHeader("Origin");
         if (allowOriginList.contains(currentOrigin)) {
           response.setHeader("Access-Control-Allow-Origin", currentOrigin);
         }
       }
     }
   }
   if (!StringUtils.isEmpty(allowMethods)) {
     response.setHeader("Access-Control-Allow-Methods", allowMethods);
   }
   if (!StringUtils.isEmpty(allowCredentials)) {
     response.setHeader("Access-Control-Allow-Credentials", allowCredentials);
   }
   if (!StringUtils.isEmpty(allowHeaders)) {
     response.setHeader("Access-Control-Allow-Headers", allowHeaders);
   }
   if (!StringUtils.isEmpty(exposeHeaders)) {
     response.setHeader("Access-Control-Expose-Headers", exposeHeaders);
   }
   filterChain.doFilter(servletRequest, servletResponse);
 }

@Override
 public void destroy() {

}
}

大功告成,现在前端就可以跨域获取后台的数据了,比其它方式容易得多,代码就不解释了,简单易懂,使用其它后台开发方式也一样,最终目的就是判断请求,设置响应头,前端什么事都不用做。

来源:http://www.jianshu.com/p/d6dc9e60c8e6?utm_source=tuicool&utm_medium=referral

标签:Java,CORS,跨域
0
投稿

猜你喜欢

  • SpringBoot中JPA实现Sort排序的三种方式小结

    2022-02-12 23:35:12
  • Java用 Rhino/Nashorn 代替第三方 JSON 转换库

    2023-11-04 02:20:26
  • java对象拷贝详解及实例

    2023-01-20 08:27:00
  • JAVA 实现磁盘文件加解密操作的示例代码

    2023-11-15 00:13:06
  • 关于java数组与字符串相互转换的问题

    2021-08-08 18:50:31
  • Java中的BaseTypeHandler自定义类型转换器的使用

    2022-03-09 00:34:16
  • C#使用Task实现异步方法

    2022-09-02 20:26:53
  • Java经典面试题最全汇总208道(三)

    2023-11-15 23:30:42
  • 从try-with-resources到ThreadLocal,优化你的代码编写方式

    2023-11-11 03:19:52
  • 支持SpEL表达式的自定义日志注解@SysLog介绍

    2023-08-27 09:38:42
  • Java多线程中关于join方法的使用实例解析

    2023-08-22 21:47:29
  • Java实现二叉堆、大顶堆和小顶堆

    2022-08-20 18:39:33
  • IDEA实用好用插件推荐及使用方法教程详解(必看)

    2021-07-15 19:10:44
  • Java实现分页代码

    2023-08-05 08:14:47
  • C# Newtonsoft.Json 解析多嵌套json 进行反序列化的实例

    2022-04-09 11:23:13
  • java二维数组实现推箱子小游戏

    2022-08-31 10:18:40
  • Java中的字符串常量池详细介绍

    2023-03-08 09:16:41
  • Spring Security和Shiro的相同点与不同点整理

    2023-01-15 17:07:20
  • 100行C#代码实现经典扫雷游戏

    2023-12-05 16:33:30
  • SpringBoot使用Thymeleaf自定义标签的实例代码

    2023-11-24 21:41:29
  • asp之家 软件编程 m.aspxhome.com