SpringBoot跨域及三种解决方式
2023-04-18 16:14:37 时间
我们先了解下【域】的定义:协议 + 域名 + 端口。三者完全相同则为同域,反之有其一不同均为不同域。那么,什么是跨域请求?当前【发起请求】的域和【请求指向】的域属于不同域时,该次请求称之为跨域请求。简单说A应用只能访问A应用后台传来数据,B应用只能访问B应用后台传来的数据,如果A应用用Ajax获取数据时的URL地址中的协议、端口、域名其中有一个和B应用对应的话,则是A应用跨域了想获取B应用数据,是不允许的。在谈跨域之前,我们先来看看浏览器的同源策略。
01
跨域的几种情况
- 同一域名下允许通信(未指定端口协议)
- 同一域名下不同文件夹允许通信
- 同一域名不同端口不允许通信
- 同一域名不同协议不允许通信
- 域名和域名对应IP不允许通信
- 主域名相同,子域名不同不允许通信
- 同一域名,不同二级域名不允许通信
- 不同域名不允许通信
01
跨域示例如下:
方法1:全局配置
定义配置类,添加@Configuration注解,实现WebMvcConfigurer接口,再重写addCorsMappings方法:
// 请求跨域
@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该注解即可。
@CrossOrigin(origins = "*",maxAge = 3600)
public class UserController {
final UserService userService;
@GetMapping("/getOne/{id}")
public User getOne(@PathVariable("id") Integer id) {
return userService.getById(id);
}
我们也可以设置更小的粒度,在方法上设置跨域:
@Controller
@RequestMapping("/shop")
public class ShopController {
@GetMapping("/")
@ResponseBody
//更小的解决跨域 设置只能某些地址访问
@CrossOrigin(originPatterns = "http://localhost:8080")
public Map<String, Object> findAll() {
//返回数据
return DataSchool.getStudents();
}
}
方法3:定义跨域过滤器
1)编写过滤器
// 跨域过滤器
@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)注册过滤器
@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
小结
网络安全涉及的范围非常广,跨域仅仅是「浏览器安全」中的一种,开发的时候也经常会碰到,希望大家多多留意。
相关文章
- 为应用赋能!博云容器云产品族正式发布
- 人工智能能否为物联网应用提供价值?
- 无影云应用启动公测 百种GB级文件无需下载即点即用
- 云原生下一步的发展方向是什么?
- 人工智能:人工神经网络的应用场景知识介绍
- 瑞数下一代WAF–WAAP平台 三大引擎全面升级应用安全防护
- 5G物联网在商业建筑中的应用
- 构建AI医学影像生态系统 NVIDIA MONAI让医疗人工智能加速落地
- 电信研究院报告显示5G室内覆盖率仅六成
- NVIDIA MONAI助于推动研发成果落地,赋能医疗行业AI创新应用
- 瑞数下一代WAF - WAAP平台,覆盖Web、APP、云和API的一站式动态主动防御
- 5G赋能,无线制造不再是梦!
- 浅谈微服务的发展以及可观测性
- 容器云平台运维学习思路和方法
- 边缘计算和边缘AI是什么?两者有什么区别?
- 红帽推进云服务组合,为现代应用开发创建一致且可扩展的体验
- 2030年5G“五大应用场景”将给运营商带来19569亿元收入
- 无需嵌码的主动式监测:一种预先感知用户体验的最佳实践
- 3G、4G、5G,我们为什么要那么多的"G"呢?
- AT&T与微软联合进行私有 5G 边缘部署