跨域访问配置
一、跨域访问问题的解决
首先你要知道什么是同源策略,什么是跨域访问,这些基础知识我就不细讲了。简单的说就是:浏览器出于安全考虑,不允许域名(ip)、端口、协议不一致的请求进行跨域访问。比如:不能从localhost:8080域(前端),去访问localhost:8201域(后端服务)。
解决办法:去后端服务中,把允许跨域访问的域和HTTP协议方法配置好。
1.localhost:8080域 和localhost:8201域。算不算同源呢
它阻止一个源加载来自不同源的资源。
2.localhost:8080域 和localhost:8201域。算不算跨域呢?
算跨域。一个源去访问另外一个源,就是跨域。
3.若依微服务使用Java配置文件在gateway中实现的跨域配置
二、gateway网关配置跨域
假设目前的我的前端应用是:localhost:8080。所有的服务都从gateway网关经过,我们要针对网关进行cors配置。
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowCredentials: true
exposedHeaders: "*"
allowedHeaders: "*"
allowedOrigins: "http://localhost:8080"
allowedMethods:
- GET
- POST
properties格式如下配置
spring.cloud.gateway.globalcors.corsConfigurations.[/**].allowedOrigins=http://localhost:8080
spring.cloud.gateway.globalcors.corsConfigurations.[/**].allowedHeaders[0]=*
spring.cloud.gateway.globalcors.corsConfigurations.[/**].allowedMethods[0]=GET
spring.cloud.gateway.globalcors.corsConfigurations.[/**].allowedMethods[1]=POST
在上面配置的示例中,从localhost:8080
所有GET或POST请求都允许跨域,浏览器端不会报错。
三、代码配置方式
虽然上面的配置是官方推荐的配置,但是我配置完成之后并未生效。随后我在源码中找到了如下的注释:
也就是说通过配置文件的配置方式目前还是TODO,有人说可以生效,有人说不生效。我测试的结果是不生效,所以可能因版本不同上面的方式不一定生效。所以我们提供另外一种配置方式:写代码,效果是一样的。在Configuration配置类或者gateway应用入口加入代码配置。
@Bean
public CorsWebFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedMethods(Arrays.asList(
HttpMethod.POST.name(),
HttpMethod.GET.name()
));
config.addAllowedOrigin("Http://localhost:8080");
config.addAllowedHeader("*");
UrlBasedCorsConfigurationSource source
= new UrlBasedCorsConfigurationSource(new PathPatternParser());
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
如果你不想在代码层面把配置内容写死,仍然可以采用nacos里面的配置属性自动组装GlobalCorsProperties及CorsWebFilter 并让第二小节中的yml中的跨域配置生效,代码如下:
@Configuration
@AutoConfigureAfter(GlobalCorsProperties.class)
public class CorsConfig {
@Resource
private GlobalCorsProperties globalCorsProperties;
@Bean
public CorsWebFilter corsFilter() {
UrlBasedCorsConfigurationSource source
= new UrlBasedCorsConfigurationSource(new PathPatternParser());
globalCorsProperties.getCorsConfigurations()
.forEach(source::registerCorsConfiguration);
return new CorsWebFilter(source);
}
}
四、需要注意的是
在gateway网关上进行了统一的跨域cors配置,微服务端就不要开启CORS跨域访问了。画蛇添足,反而会出错!