0
点赞
收藏
分享

微信扫一扫

SpringBoot 解决跨域问题


​​前言​​

前后端分离大势所趋,跨域问题更是老生常谈,随便用标题去google或百度一下,能搜出一大片解决方案,那么为啥又要写一遍呢,不急往下看。

问题背景:

Same Origin Policy,译为“同源策略”。它是对于客户端脚本(尤其是JavaScript)的重要安全度量标准,其目的在于防止某个文档或者脚本从多个不同“origin”(源)装载。它认为自任何站点装载的信赖内容是不安全的。

当被浏览器半信半疑的脚本运行在沙箱时,它们应该只被允许访问来自同一站点的资源,而不是那些来自其它站点可能怀有恶意的资源。

注:具有相同的Origin,也即是拥有相同的协议、主机地址以及端口。一旦这三项数据中有一项不同,那么该资源就将被认为是从不同的Origin得来的,进而不被允许访问。

CORS就是为了解决SOP问题而生的,当然CORS不是唯一的解决方案,不过这里不赘述其他解决办法了。

CORS简介:

CORS是一个W3C标准,全称是"跨域资源共享”(Cross-origin resource sharing)。它允许浏览器向跨源(协议 + 域名 + 端口)服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。CORS需要浏览器和服务器同时支持。它的通信过程,都是浏览器自动完成,不需要用户参与。

对于开发者来说,CORS通信与同源的AJAX/Fetch通信没有差别,代码完全一样。浏览器一旦发现请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

  • 浏览器发出CORS简单请求,只需要在头信息之中增加一个Origin字段。
  • 浏览器发出CORS非简单请求,会在正式通信之前,增加一次OPTIONS查询请求,称为"预检"请求(preflight)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

 

springboot跨域配置

方式1

@Configuration
public class CorsConfig {

@Autowired
private AllowedOriginConfig allowedOriginConfig;

@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowCredentials(true);
if (allowedOriginConfig.getAddresses().size() > 0) {
corsConfiguration.setAllowedOrigins(allowedOriginConfig.getAddresses());
} else {
// 允许任何域名
corsConfiguration.addAllowedOrigin(CorsConfiguration.ALL);
}

// 允许任何头部信息
corsConfiguration.addAllowedHeader(CorsConfiguration.ALL);
// 允许所有请求类型
corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
corsConfiguration.addExposedHeader("Authorization");
source.registerCorsConfiguration("/**", corsConfiguration);
FilterRegistrationBean bean = new FilterRegistrationBean<>(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
}

}

@Data
@Configuration
@ConfigurationProperties(prefix = "answer.allowed.origin")
public class AllowedOriginConfig {

List<String> addresses = new ArrayList<>();

}

answer:
allowed:
origin:
addresses:
- http://192.168.65.0.30:8080
- http://192.168.1.1:8080
- http://192.168.1.2:8080

# answer.allowed.origin.addresses[0]=http://192.168.0.30:8080
# answer.allowed.origin.addresses[1]=http://192.168.1.1:8080
# answer.allowed.origin.addresses[2]=http://192.168.1.2:8080

 

​​方式2​​

public class CORSConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 允许所有跨域访问
// registry.addMapping("/**");

registry.addMapping("/api/**")
.allowedOrigins("http://www.exception.site")
.allowedMethods("POST", "GET");
}

}

 

​​方式3​​

public class GoodsController {
@CrossOrigin(origins = "http://localhost:4000")
@GetMapping("execute")
public Response execute(@RequestParam String goodsUrl) throws Exception {

}
}

没错就是 @CrossOrigin 注解,点开注解

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {

}

从元注解@Target可以看出,注解可以放在method、class等上面,类似RequestMapping,也就是说,整个controller下面的方法可以都受控制,也可以单个方法受控制。

也可以得知,这个是最小粒度的cors控制办法了,精确到单个请求级别。


举报

相关推荐

0 条评论