# 关于跨域的问题
还没有在本地调试出跨域问题, 但是项目一般都是前后分离的, 熟悉这一块是非常必要的.
# 跨域问题的起因
网上搜索跨域, 就能得到原因, 都会告诉你, 这是浏览器的同源策略导致. 当我看了两篇文章后, 发现还是对跨域的起因有点懵逼, 因此在这里总结一下跨域.
# 什么情况下是跨域
浏览器打开一个前端页面, 上面有ajax请求另一个项目(域名?)的链接.此时就会出现跨域问题, 这是浏览器做出的安全控制.
# 测试跨域
- 启动一个前端项目或html页面, 里面写入ajax请求到其他域名
- 此处的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("/**");
}
}
/*但如果有拦截器, 会先进入拦截器, 如果被拦截住, 就不会进入这里了, 最终导致设置无效, 因此这种方式不推荐使用.*/
← 公钥私钥原理 分库分表中间件的设计与实现 →