springboot解决跨域问题

3 篇文章 0 订阅
3 篇文章 0 订阅

springboot解决跨域问题

基本概念:
1、同源策略:是指协议、域名、端口都要相同,只要有一个不相同,就是跨域。
注:跨域限制访问是浏览器的限制
2、CORS:跨域资源共享,这是一种机制,允许web服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。

注:很赞的一篇介绍CORS的文章
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

问题演变和改进过程

1、前后端分离开发,后端使用springboot框架提供http接口,因为没有满足同域条件,从而出现了跨域访问问题。

2、首先使用的解决方案是实现这个WebMvcConfigurer这个接口,实现addCorsMappings这个方法。

@Override
    public void addCorsMappings(CorsRegistry registry) {
        // 设置允许跨域的路径
        registry.addMapping("/**")
                // 设置允许跨域请求的域名
                .allowedOrigins(GlobalConstants.ALLOW_HOSTS)
                .allowedHeaders("*")
                // 是否允许证书 不再默认开启
                .allowCredentials(true)
                // 设置允许的方法
                .allowedMethods("*")
                // 跨域允许时间
                .maxAge(3600);
    }

3、通过这样的配置的确解决了跨域问题,但是呢,因为需要在服务端配置权限验证,就是控制访问http接口的权限,主要是从cookie中拿取一个字段进行校验,因此配置了一个权限验证拦截器,配置了这个有出事了。。。因为拦截器的执行顺序和addCorsMappings这个方法的执行有顺序问题,当请求被拦截后,addCorsMappings这个方法所设置的跨域配置没起作用,从而又出现了跨域问题。。这时候该怎么办呢?
借助于过滤器来设置跨域问题,让跨域的设置在拦截器的权限验证之前,过滤器的设置如下:

@Component
@Order(1)
@WebFilter(urlPatterns = "/**")
public class CORSFilter implements Filter {

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {

  }

  @Override
  public void destroy() {

  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
      HttpServletRequest httpServletRequest = (HttpServletRequest)request;
      HttpServletResponse httpServletResponse = (HttpServletResponse) response;
      String orign = httpServletRequest.getHeader("Origin");
      if(Arrays.asList(GlobalConstants.ALLOW_HOSTS).contains(orign)) {
          httpServletResponse.setHeader("Access-Control-Allow-Origin", orign);
          httpServletResponse.setHeader("Access-Control-Allow-Methods", "*");
          httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
          httpServletResponse.setHeader("Access-Control-Allow-Headers", "Content-Type,Accept,token,X-Requested-With");
          httpServletResponse.setHeader("Access-Control-Max-Age", "3600");
      }
      chain.doFilter(request, response);
  }
}

4、以为这样就完事了?又踩到了一个坑。涉及到tomcat的版本问题。报错如下:(这个错误是启动时tomcat报的错误,但是要把这个错误打出来,需要进行启动时logging.properties的配置)。

错误信息:
java.lang.AbstractMethodError: com.jd.trade.o2n.soa.web.filter.CORSFilter.init(Ljavax/servlet/FilterConfig;)V

大概意思是init是抽象方法,没有实现。本地的Filter接口用的是tomcat9版本的,init和destory方法都提供了默认的实现了,不需要额外实现。看上面的init和destory方法,之前代码中是没有的,只提供了doFilter的实现。但是在预发布发时,使用的是tomcat8,这两个方法没有提供默认实现,启动时tomcat启动不起来。比较难受的是tomcat的错误日志一直找不到地方看。结果参考网上的说法,才把tomcat的错误日志打印出来,从而发现了问题。习惯看catlina中的日志,但是没啥关键信息。

总结:上面是踩过的一些坑,但是呢,也学到了很多。愿与大家共勉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值