专栏名称: 程序员鱼皮
鹅厂全栈开发,持续分享编程技法和实用项目
目录
相关文章推荐
生物学霸  ·  研究了今年 500 ... ·  昨天  
BioArt  ·  Nature | ... ·  2 天前  
生物学霸  ·  中国医学科学院/北京协和医学院 ... ·  3 天前  
51好读  ›  专栏  ›  程序员鱼皮

Spring Boot 处理跨域竟然有坑?

程序员鱼皮  · 公众号  ·  · 2024-07-30 12:50

正文

此答案节选自我们最近弄的 面试鸭小程序 ,更多 大厂常问面试题 ,可以点击下面的小程序进行阅读哈!


首先我们来了解下 Spring Boot 处理跨域请求的几种方式:

1)局部配置 CORS,在 controller 上使用 @CrossOrigin 注解。这种方式简单直接,适合对类进行跨域设置。

2)全局配置 CORS,可以通过实现 WebMvcConfigurer 接口并重写 addCorsMappings 方法,可以对整个应用程序进行统一的跨域配置。

3)还可以添加 CorsFilter 来处理跨域请求。(或者可以自定义 Filter,但是没必要,因为本身已经提供了 CorsFilter)

扩展 cors 策略配置参数说明

addCorsMappings 部分参数说明(CorsFilter 同理):

  • addMapping("/**"):允许所有路径的请求。
  • allowedOrigins("https://mianshiya.com"):允许来自 https://mianshiya.com 的请求。
  • allowedMethods("GET", "POST", "PUT", "DELETE"):允许的 HTTP 方法。
  • allowedHeaders("*"):允许的请求头。
  • allowCredentials(true): 是否允许发送 Cookie。
  • maxAge(3600):预检请求的缓存时间,单位为秒。

如果用了 addCorsMappings 可能有有坑!

假如我们配置了 addCorsMappings ,项目里还用了 Interceptor,此时就会发生问题!

例如部分接口需要 jwt 权限验证:

 public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new JwtInterceptor()).addPathPatterns("/user/**").
                excludePathPatterns("/login");
    }

正常请求是没问题的,但是部分请求没带 token 的话,此时浏览器直接报跨域问题,好像 addCorsMappings 失效了一样。

主要原因是因为请求顺序导致的,请求会先进入拦截器,默认配置了 addCorsMappings 操作后,实际上会加了一个 CorsInterceptor, 但是这个拦截器的优先级在最后

所以,如果一个请求被前面的拦截器拦截后,直接返回,就不会经过 CorsInterceptor,这样一来返回的响应头上就不包含跨域的相关信息,因此浏览器就会继续报跨域错误!

此时有一种方法,就是在 JwtInterceptor 内直接放行预检请求,让它能访问到 CorsInterceptor 添加响应头。

if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
    return true;
}

还有一种更优雅的方式就是使用 CorsFilter

Filter 是过滤器,它是属于 servlet,而 Interceptor 是属于 Spring 的,因此 Filter 执行的优先级高于 Interceptor。

扩展:什么是跨域和同源策略

跨域请求

指的是浏览器从一个不同于当前网页所在的域名向另一个域名发起的请求。比如从 https://mianshiya.com 向 https://api.mianshiya.com 发起请求。

同源策略

它是浏览器的安全策略,只允许同源( 协议、域名、端口都相同 )的请求,跨域请求默认会被阻止。







请到「今天看啥」查看全文