服务1 ---->网关 ----> 服务2(网关和服务都要加入到注册中心中去 加依赖 写地址 加注解)
1、服务1 -->网关(port:88)
在.js文件中定义了api接口的请求地址 (地址改为网关地址88,并加上api请求,方便网关断言处理)
服务1发送请求后,请求头:
此时说明 给网关发送成功
在网关 application.yml 中 设置网关转发
predicates断言条件满足 网关就转发给 uri 地址 lb负载均衡
spring:
cloud:
gateway:
routes:
- id : admin_route
uri: lb://服务2地址
predicates:
- Path=/api/**
如代码,以上为 如果请求为 /api/**(服务1发送) 网关(88)就发送给 服务2. 8080端口
地址会有如下改变
http://localhost:88/api/captcha.jpg --> http://localhost:8080/api/captcha.jpg
但是正确访问的地址是 http://localhost:8080/server2/captcha.jpg
这就用到 GatewayFilter Factories 功能 RewritePath 重写路径,还是在application.yml 中
predicates:
- Path=/api/**
filters :
- RewritePath=/api/(?<segment>.*),/server2/$\{segment}
此时路径转发正确
http://localhost:88/api/captcha.jpg --> http://localhost:8080/server2/captcha.jpg
此时 server1可以i访问server2的captcha.jpg
如果是前后端分离还能出现
访问被拒绝的情况
Forbidden login请求被拒绝,因为 CORS policy 跨域限制, 原因是请求头没有Access-Control-Allow-Origin
解释下跨域
跨域是浏览器对javascript施加的安全限制,只要协议、域名、端口有一个不一样、就不允许访问。
请求也有限制
如果是简单请求 GET POST 则可以访问
如果或是非简单请求,则要先发送预检请求OPTIONS
如果OPTIONS允许,才会发送真实请求,发了两次
解决办法
1、使用Nginx将所有服务部署在同一域下
nginx配置好反向代理、只访问nginx地址
2、配置请求允许跨域
既然跨域需要问服务器能不能跨、 那么服务器直接告诉他,能跨域就可以了
由于网关代理其他服务,则在网关里面加一个过滤器 filter加上允许跨域即可
Springboot提供了 CorsWebFilter 只需要把配置的内容放到这个filter里,然后把这个filter放到Springboot容器中,配置的内容就可以起作用,配置类如下
@Configuration //声名该类为配置类
public class ACorsConfiguration {
@Bean //将filter注入到Springboot容器中
public CorsWebFilter corsWebFilter(){
CorsWebFilter cf = new CorsWebFilter(source);//filter需要传参数 CorsConfigurationSource跨域配置信息
//new的时候发现他是一个接口 所以要new它的是实现类 UrlBasedCorsConfigurationSource();
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
//调用它的registerCorsConfiguration方法给 /**所有请求 都设计配置
source.registerCorsConfiguration("/**",corsConfiguration);
//new 配置对象, 往配置对象里加各种配置
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedHeader("*"); //允许所有头进行跨域
corsConfiguration.addAllowedMethod("*"); //允许所有方法进行跨域
corsConfiguration.addAllowedOrigin("*"); //允许所有请求来源进行跨域
corsConfiguration.setAllowCredentials(true); //是否允许携带Cookie进行跨域
return cf;//
}
}
如果显示多个true,多个地址,
可能是 重复配置跨域
找到config/CorsConfig.class 注释掉一个,留下一个即可