# 关于跨域的问题

还没有在本地调试出跨域问题, 但是项目一般都是前后分离的, 熟悉这一块是非常必要的.

# 跨域问题的起因

网上搜索跨域, 就能得到原因, 都会告诉你, 这是浏览器的同源策略导致. 当我看了两篇文章后, 发现还是对跨域的起因有点懵逼, 因此在这里总结一下跨域.

# 什么情况下是跨域

浏览器打开一个前端页面, 上面有ajax请求另一个项目(域名?)的链接.此时就会出现跨域问题, 这是浏览器做出的安全控制.

# 测试跨域

  1. 启动一个前端项目或html页面, 里面写入ajax请求到其他域名
  2. 此处的ajax请求其他域名, 符合以下情况才会出现跨域问题, 同源策略是限制js和ajax的, 即协议+主机名+端口号相同才是非跨域. 对于html其他的标签是不做控制的.
- url不同端口
- 不同域名
- 协议不同

# 实际遇到跨域的场景

一般上线的项目中, 是不会遇到这种情况, 因为所有的服务通常在一个域名下. 你可能以为服务对应端口不同, 但从浏览器角度看, 是一样的, 因为你使用的是反向代理. 在前后端项目开发过程中, 则会遇到跨域问题, 联调时, 前后端服务跑在各自环境中, 因此需要解决跨域问题.

# 跨域的解决方案

1. jsonp

2. cors

3. 反向代理

# spring解决跨域问题的方法

1. 配置corsFilter

@Configuration
public class CorsConfig {

    private CorsConfiguration corsConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.setMaxAge(3600L);
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfig());
        return new CorsFilter(source);
    }

}

2. 配置FilterRegistrationBean

@Bean
    public FilterRegistrationBean<CorsFilter> corsFilter(){
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
        bean.setOrder(0);
        return bean;
    }

3. 配置WebMvcConfigurerAdapter

@Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
		.allowedOrigins("*")
                .allowCredentials(true)
                .allowedMethods("*")
                .allowedHeaders("*")
                .maxAge(3600);
            }
        };
    }
/*以上方法提示过期, 不推荐使用, 因此有了以下方式, 继承WebMvcConfigurerAdapter*/
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}
/*但如果有拦截器, 会先进入拦截器, 如果被拦截住, 就不会进入这里了, 最终导致设置无效, 因此这种方式不推荐使用.*/
修改于: 8/11/2022, 3:17:56 PM