前端项目会在index.js中配置api接口的基本请求路径
比如路径为 http://localhost:88/api
window.SITE_CONFIG['baseUrl'] = 'http://localhost:88/api';
为什么会是这个请求呢,首先前端项目要向后端发数据,肯定要现发送给微服务中的网关gateway,而gateway中配置的端口为88
但前端项目的启动端口为8001
从8001端口向88端口发送请求,必然是跨域请求
所以我们要在服务端对请求进行过滤,服务端收到请求之后,通过 过滤器 在请求响应的时候,在响应头中添加进入允许跨域的信息。但是之前我们不是说浏览器会拦截跨域请求吗?为什么请求还能到达服务端呢?
因为浏览器有一个特殊的请求,也就是预检请求。
所有非简单请求,现在可以简单理解为除了GET、POST的请求,都会先向服务器发送一个预检请求,询问服务器是否允许跨域访问,我们要做的就是在预检请求的时候,向预检请求的响应头中加入允许访问的策略。
@Configuration
public class GulimallCorsConfiguration {
@Bean
public CorsWebFilter corsWebFilter(){
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
//1、配置跨域
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.setAllowCredentials(true);
source.registerCorsConfiguration("/**",corsConfiguration);
return new CorsWebFilter(source);
}
}
通过编写一个简单的配置文件,暂时让所有的请求方法,参数等都允许跨域,这样在返回的预检请求的请求头中就会出现下面这样
这里我们可以看到
请求的方式 是 options
请求的地址 http://localhost:88/api/sys/login
请求源(Access-Control-Allow-Origin)是 http://localhost: 8001
网关接收到请求后需要根据路由将请求转发给对应的微服务,这里需要配置路由断言
spring:
cloud:
gateway:
routes:
- id: admin_route
uri: lb://renren-fast
predicates:
- Path=/api/**
filters:
- RewritePath=/api/(?<segment>.*),/renren-fast/$\{segment}
这里通过路由断言predicates, 如果接收到了以/api开头的请求 ,则使用路由过滤器filters,
将以/api开头的请求转换为以/renren-fast开头的路径,后面携带的参数不变,例如
原来的路由请求
http://localhost:88/api/captcha.jpg
通过路由断言和过滤器之后 变成
http://localhost:88/renren-fast/captcha.jpg
这样就可以将所有非同源请求进行放行,完成跨域访问。
当然这只是在开发阶段为了方便前后端联调,在项目上线的时候使用的是nginx服务器进行反向代理,后面会更新使用nginx完成跨域请求的策略