前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot跨域及三种解决方式

SpringBoot跨域及三种解决方式

作者头像
崩天的勾玉
发布2021-12-24 13:13:18
23.4K1
发布2021-12-24 13:13:18
举报
文章被收录于专栏:崩天的勾玉

我们先了解下【域】的定义:协议 + 域名 + 端口。三者完全相同则为同域,反之有其一不同均为不同域。那么,什么是跨域请求?当前【发起请求】的域和【请求指向】的域属于不同域时,该次请求称之为跨域请求。简单说A应用只能访问A应用后台传来数据,B应用只能访问B应用后台传来的数据,如果A应用用Ajax获取数据时的URL地址中的协议、端口、域名其中有一个和B应用对应的话,则是A应用跨域了想获取B应用数据,是不允许的。在谈跨域之前,我们先来看看浏览器的同源策略

01

跨域的几种情况

  • 同一域名下允许通信(未指定端口协议)
  • 同一域名下不同文件夹允许通信
  • 同一域名不同端口不允许通信
  • 同一域名不同协议不允许通信
  • 域名和域名对应IP不允许通信
  • 主域名相同,子域名不同不允许通信
  • 同一域名,不同二级域名不允许通信
  • 不同域名不允许通信

01

跨域示例如下:

方法1:全局配置

定义配置类,添加@Configuration注解,实现WebMvcConfigurer接口,再重写addCorsMappings方法:

代码语言:javascript
复制
// 请求跨域
@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        //添加映射路径
        registry.addMapping("/**")
                //是否发送Cookie
                .allowCredentials(true)
                //设置放行哪些原始域   SpringBoot2.4.4下低版本使用.allowedOrigins("*")    
                .allowedOriginPatterns("*")
                //放行哪些请求方式
                .allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"})
                //.allowedMethods("*") //或者放行全部
                //放行哪些原始请求头部信息
                .allowedHeaders("*")
                //暴露哪些原始请求头部信息
                .exposedHeaders("*");
    }
}

方法2:局部跨域

Controller层在需要跨域的类或者方法上加上@CrossOrigin该注解即可。

代码语言:javascript
复制
@CrossOrigin(origins = "*",maxAge = 3600)
public class UserController {
 final UserService userService;
 
 @GetMapping("/getOne/{id}")
 public User getOne(@PathVariable("id") Integer id) {
  return userService.getById(id);
 }

我们也可以设置更小的粒度,在方法上设置跨域:

代码语言:javascript
复制
@Controller
@RequestMapping("/shop")
public class ShopController {

    @GetMapping("/")
    @ResponseBody
    //更小的解决跨域 设置只能某些地址访问
    @CrossOrigin(originPatterns = "http://localhost:8080")
    public Map<String, Object> findAll() {
        //返回数据
        return DataSchool.getStudents();
    }
}

方法3:定义跨域过滤器

1)编写过滤器

代码语言:javascript
复制
// 跨域过滤器
@Component
public class CORSFilter implements Filter {
 
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  //*号表示对所有请求都允许跨域访问
        HttpServletResponse res = (HttpServletResponse) response;
        res.addHeader("Access-Control-Allow-Credentials", "true");
        res.addHeader("Access-Control-Allow-Origin", "*");
        res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
        res.addHeader("Access-Control-Allow-Headers", "Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN");
        if (((HttpServletRequest) request).getMethod().equals("OPTIONS")) {
            response.getWriter().println("Success");
            return;
        }
        chain.doFilter(request, response);
    }
 
    @Override
    public void destroy() {
 
    }
 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
 
    }
}

2)注册过滤器

代码语言:javascript
复制
@Configuration
public class CorsConfig {
 
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsFilter(urlBasedCorsConfigurationSource);
    }
 
}

03

小结

网络安全涉及的范围非常广,跨域仅仅是「浏览器安全」中的一种,开发的时候也经常会碰到,希望大家多多留意。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 崩天的勾玉 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档