跨域,解决这个问题不单是前端同学的问题,也需要后端的配合,那么后端如何看待跨域问题?还要从jsonp,cors请求等方面入手吗?其实从请求发出开始,跨域应该在请求时解决,但并不是唯一的解决方式。
什么是跨域?
同源策略:所谓同源是指,域名,协议,端口均相同,只要有一个不同,就是跨域
前端解决跨域的方式不等,从后端的角度解决跨域,前段时间写了一段时间的全栈,在请求ajax时并没有用jsonp,项目也没有配置nginx,当前后端分离,或者后端写前端的时候,如何解决跨域?==>服务网关
在项目请求打进来的时候,首先进入nginx反向代理,分发请求,随后打入网关,网关的角色是作为一个 API 架构,用来保护、增强和控制对于 API 服务的访问。
网关的工作流程:路由转发 执行过滤器链
工作流程:官网
API 网关是一个处于应用程序或服务(提供 REST API 接口服务)之前的系统,用来管理授权、访问控制和流量限制等,这样 REST API 接口服务就被 API 网关保护起来,对所有的调用者透明。因此,隐藏在 API 网关后面的业务系统就可以专注于创建和管理服务,而不用去处理这些策略性的基础设施。
客户端向Spring Cloud Gateway发出请求。如果网关处理程序映射确定请求与路由匹配,则将其发送到网关Web处理程序。该处理程序通过特定于请求的过滤器链运行请求。筛选器由虚线分隔的原因是,筛选器可以在发送代理请求之前和之后运行逻辑。执行所有“前置”过滤器逻辑。然后发出代理请求。发出代理请求后,将运行“后”过滤器逻辑。
工作原理:
Filter过滤器,对请求资源进行过滤,请求到达服务器,判断url是否可路由,通过id,uri,断言由绝对路径进行路由,如果配置/**表示某前缀url可全部通过,在request请求里进行过滤。
yml
代码语言:javascript复制spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称j进行路由
routes:
- id: payment_route # 路由的id,没有规定规则但要求唯一,建议配合服务名
#匹配后提供服务的路由地址
uri: http://localhost:8001
predicates:
- Path=/payment/get/** # 断言,路径相匹配的进行路由
#- After=2017-01-20T17:42:47.789-07:00[America/Denver]
#- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
#- Cookie=username,zzyy
#- Header=X-Request-Id, d #请求头要有X-Request-Id属性,并且值为正数
#- Host=**.**.com
#- Method=GET
#- Query=username, d # 要有参数名username并且值还要是正整数才能路由
# 过滤
#filters:
# - AddRequestHeader=X-Request-red, blue
- id: payment_route2
uri: http://localhost:8001
predicates:
Path=/payment/lb/** #断言,路径相匹配的进行路由
请求到达localhost:9527/payment/get/31:
代码语言:javascript复制public class MyLogGatewayFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("come in global filter: {}", new Date());
ServerHttpRequest request = exchange.getRequest();
String uname = request.getQueryParams().getFirst("uname");
if (uname == null) {
log.info("用户名为null,非法用户");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
// 放行
return chain.filter(exchange);
}
/**
* 过滤器加载的顺序 越小,优先级别越高
*
* @return
*/
@Override
public int getOrder() {
return 0;
}
}
debug
网关过滤
代码语言:javascript复制https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gatewayfilter-factories
可在代码中单独配置
代码语言:javascript复制@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("come in global filter: {}", new Date());
↓↓↓↓↓↓↓
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
ServerHttpRequest request = exchange.getRequest();
String uname = request.getQueryParams().getFirst("uname");
if (uname == null) {
log.info("用户名为null,非法用户");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
// 放行
return chain.filter(exchange);
}
总的来说,后端解决跨域应从后端组件入手,nginx配置请求固然可以解决,但是每次添加新的功能还要配置url,不如从网关方面入手,个人观点。