SpringBoot彻底解决跨域的问题

SpringBoot解决跨域问题

2022.8.24,时隔两年多,对跨域有了更近一步的认知,原先的解决方案越发觉得过于粗暴,果然前段时间出了问题。

基于springboot的全局跨域配置策略是加过滤器,但是很多时候,我们并不会自己撸一个过滤器,而是会去实现mvc的拦截器做跨域处理。

@Configuration
public class WebAppConfigurer implements WebMvcConfigurer 
{
	  @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowCredentials(true)
                .allowedOrigins("*")
                .allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"})
                .allowedHeaders("*")
                .exposedHeaders("*");
    }
}

上面的代码乍一看没什么问题,某些情况下是能起到跨域处理的效果。
但是,我最近接手一个项目的时候,需要在这个项目中加上用户认证的拦截器,就发现了问题,而且是大问题!

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private LoginInterceptor loginInterceptor;

    //注册拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor).addPathPatterns("/**")
                .excludePathPatterns("/sys/login")
                .excludePathPatterns("/error", "/csrf")
                .excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**");
    }

原来的代码就是上面两个配置写到一起了,这个时候你就会发现,你所有的请求,都是跨域的!
奇了怪了,明明配了啊,为什么还会跨域呢?这个必须要读一读源码才能知道!等有时间了再回来记录问题的根本原因,这边先记录解决方案!

解决方案就是:

  1. 跨域配置使用下面原来文章中贴的的过滤器,
  2. 用户认证的拦截器使用上面贴的烂机器代码。
    因为过滤器会在拦截器之前被触发,所以跨域的问题解决了!(撒花!!!)

以下是原文章(2020.4.9)

接触Java的时间并不是很长,我一直以为跨域是前端需要解决的问题。直到有一天,一个前端的技术经理跟我说cityMaker无法处理跨域问题的时候,我才意识到跨域问题的严重性。因此有了这篇文章。

跨域

在说明跨域之前,我还是希望能把问题由来还原,以加深对这次过程的印象。
这次的后端接口不多,就几个统计数据的接口,前端使用cityMaker做的大屏端展示数据(美名曰“驾驶仓”)。由于驾驶仓部署在其他远程服务器上,而后端接口在另外一台服务器,所以就出现了跨域问题。(这个原因是前端的技术经理跟我说的,我没有权限接触驾驶仓的服务器,所以就按照这个原因算吧!)

跨域
跨域通常指的是浏览器对javascript的同源策略的限制。
比如我碰到的问题就是浏览器相当于cityMaker,而后端服务相当于脚本,浏览器出于安全考虑,是无法得到我的后端服务数据的。

用几个例子展示可能会有更加清晰的认识:

例子中均为 index.html 调用 hello 服务。
在这里插入图片描述
上述情况非跨域。
在这里插入图片描述
上述情况跨域,因为图中的主域名不一样。
在这里插入图片描述
上述情况跨域,因为图中的子主域名不一样。
在这里插入图片描述
上述情况跨域,因为图中的端口不一样,hello默认使用ng的80端口代理。
在这里插入图片描述
上述情况跨域,因为图中的协议不一样。

思考

看到这里需要有一个疑问,当我们在本地调试的时候,用127.0.0.1调用localhost会跨域吗?

SpringBoot中解决跨域

SpringBoot中解决跨域我一般采用两种办法。

  1. 利用SpringBoot自己原生的跨域策略,在Controller上添加注解 @CrossOrigin
    在这里插入图片描述

@CrossOrigin的更多用法需要自行搜索。

需要的同学可以参考博客园大佬 淼淼之森 的文章:注解@CrossOrigin解决跨域问题

  1. 自己写一个过滤器,放行跨域请求,过滤器的规则可以视项目情况做修改。
@Component
public class SimpleCORSFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*"); //解决跨域访问报错
        response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600"); //设置过期时间
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, client_id, uuid, Authorization, access_token");
        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {}

    public void destroy() {}

}
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值