什么是跨域问题 ?Spring MVC 如何解决跨域问题 ?Spring Boot 如何解决跨域问题 ?

目录

1. 什么是跨域问题 ?

2. Spring MVC 如何解决跨域问题 ?

3. Spring Boot 如何解决跨域问题 ? 


1. 什么是跨域问题 ?

跨域问题指的是不同站点之间,使用 ajax 无法相互调用的问题。

跨域问题的 3 种情况:

1. 协议不同,例如 http 和 https;

  • http://127.0.0.1:8080
  • https://127.0.0.1:8080

2. 域名不同;

  • 一级域名、二级域名..不同,都算跨域请求

3. 端口不同.

  • 80
  • 443

什么是跨域问题 ?Spring MVC 如何解决跨域问题 ?Spring Boot 如何解决跨域问题 ?_第1张图片

为什么要有跨域问题 ?

        跨域问题本质上是浏览器的一种保护机制,它诞生的初衷是为了保证用户的安全,防止恶意网站窃取数据。但是这个保护机制也带来新的问题,它使得不同站点之间的正常调用,也会遇到阻碍。

2. Spring MVC 如何解决跨域问题 ?

1. 定义一个配置类;

2. 在配置类中写一个方法,返回 WebMvcConfigurer 对象,并重写 addCorsMappings 方法。

@Configuration
public class MyConfiguration {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                // 设置允许跨域的请求规则【响应头里添加标识】
                registry.addMapping("/api/**");
            }
        };
    }
}

        跨域问题,它的请求可以到达后端,只不过在后端返回响应给前端的时候,浏览器会做跨域问题的验证。

为什么不在前端验证 ?

因为前端代码是可以修改的,通过开发者工具都是可以伪造的,所以在前端验证没有意义。

什么是跨域问题 ?Spring MVC 如何解决跨域问题 ?Spring Boot 如何解决跨域问题 ?_第2张图片

3. Spring Boot 如何解决跨域问题 ? 

在 Spring Boot 中,解决跨域问题常见的方式有 5 种 :

1. 使用 @CrossOrigin 注解实现跨域;【局部跨域

2. 通过配置文件实现跨域;最常见 - 全局跨域】

3. 通过 CorsFilter 对象实现跨域;【全局跨域

4. 通过 Response 对象实现跨域;【局部跨域

5. 通过实现 ResponseBodyAdvice 实现跨域。次常见 - 全局跨域】

具体的实现如下:

① 使用 @CorsOrigin 注解实现跨域

        @CorsOrigin 注解既可以加在类上,又可以加在方法上,修饰类表示这个类种所有接口都可以跨域,修饰方法表示这个方法可以跨域。

@RestController
@CrossOrigin(origins = "*")
public class TestController {
    @RequestMapping("/test")
    public HashMap test() {
        HashMap map = new HashMap<>();
        map.put("code",200);
        map.put("data","success");
        map.put("msg","");
        return map;
    }
}

这种方式只能实现局部跨域,当一个项目中有多个类的时候,使用这种方式就会比较麻烦。

② 通过配置文件实现跨域

  • 创建一个新的配置类;
  • 添加 @Configuration 注解,实现 WebMvcConfigurer 接口;
  • 重写 addCorsMappings 方法,设置允许跨域。

这种方式可以实现全局跨域,和 Spring MVC 里面一样:

@Configuration
public class MyConfiguration implements WebMvcConfigurer{
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        // 设置允许跨域的请求规则
        registry.addMapping("/**")
                .allowCredentials(true) // 是否发送 Cookie
                .allowedOriginPatterns("*") // 支持跨域
                // 支持方法
                .allowedMethods(new String[]{"GET","POST","PUT","DELETE"})
                .allowedHeaders("*")
                .exposedHeaders("*");
    }
}

③ 通过 CorsFilter 对象实现跨域

这种方式和方式 ② 类似,只不过此处是通过给方法加上 @Bean 注解,返回一个 CorsFilter 对象

④ 通过 Response 对象实现跨域

这种方式是解决跨域问题最原始的方式,它可以支持所有版本的 Spring Boot,但是这种方式也是局部跨域。

@RestController
public class TestController {
    @RequestMapping("/test")
    public HashMap test(HttpServletResponse response) {
        // 设置跨域
        response.setHeader("Access-Control-Allow-Origin","*");
        return new HashMap() {{
            put("code",200);
            put("data","success");
            put("msg","");
        }};
    }
}

⑤ 通过实现 ResponseBodyAdvice 实现跨域

        这个接口可以用于集中统一处理,在统一数据返回的时候,我们就可以实现这个接口,在数据即将返回给前端的时候,在响应头种加上一个 “我是自己人” 的标识,就可以实现跨域了,这种方式也是全局跨域。

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true; // 返回 true, 才能执行后续方式
    }
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        // 设置跨域
        response.getHeaders().set("Access-Control-Allow-Origin","*");
        return body;
    }
}

你可能感兴趣的:(JavaEE进阶,spring,mvc)