跨域

一、什么是跨域?

当一个请求的协议、域名、端口三者之间任意一个与当前页面的URL不同即为跨域

当前页面url 被请求的页面url 是否跨域 原因
http://localhost:8080/ http://localhost:8080/index.html 协议端口号,域名端口号相同
http://localhost:8080/ https://localhost:8080/index.html 协议不同
http://localhost:8080/ http://www.baidu.com/ 域名不同
http://localhost:8080/ http://www.blog.baidu.com/ 域名不同
http://localhost:8080/ http://localhost:9999/ 端口号不同

二、跨域的限制

  1. 无法读取cookie,session
  2. 无法加载非同源DOM
  3. 无法发送AJAX,axios请求

三、java 后端实现CORS跨域请求的方式

对于CORS的跨域请求,主要有以下几种方式可供选择:

  1. 配置返回新的CorsFliter
  2. 配置 WebMvcConfigurer
  3. 使用注解@CrossOrigin
  4. 手动设置响应头(HttpServletResponse)
  5. 自定web fliter 实现跨域

1.返回新的CorsFliter(全局跨域)

注入一个新的配置类

@Configuration
public class GlobalCorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        //1. 添加 CORS配置信息
        CorsConfiguration config = new CorsConfiguration();
        //放行哪些原始域
        config.addAllowedOrigin("*");
        //是否发送 Cookie
        config.setAllowCredentials(true);
        //放行哪些请求方式
        config.addAllowedMethod("*");
        //放行哪些原始请求头部信息
        config.addAllowedHeader("*");
        //暴露哪些头部信息
        config.addExposedHeader("*");
        //2. 添加映射路径
        UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();
        corsConfigurationSource.registerCorsConfiguration("/**",config);
        //3. 返回新的CorsFilter
        return new CorsFilter(corsConfigurationSource);
    }
}

2.重写WebMvcConfigurer(全局跨域)

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                //是否发送Cookie
                .allowCredentials(true)
                //放行哪些原始域
                .allowedOrigins("*")
                .allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"})
                .allowedHeaders("*")
                .exposedHeaders("*");
    }
}

3.使用注解(局部跨域)

对类使用,该类允许跨域

@RestController
@CrossOrigin(origins = "*")
public class HelloController {
    @RequestMapping("/hello")
    public String helloWorld() {
        return "hello world";
    }
}

在方法上使用,表示该方法允许跨域

@RequestMapping("/hello")
    @CrossOrigin(origins = "*")
     //@CrossOrigin(value = "http://localhost:8081") //指定具体ip允许跨域
    public String helloWorld() {
        return "hello world";
    }

4.手动设置响应头(局部跨域)

@RequestMapping("/index")
public String index(HttpServletResponse response) {
    response.addHeader("Access-Allow-Control-Origin","*");
    return "index";
}

还可以根据优化为自定义fliter,集中设置响应头

response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");