后端如何解决跨域请求问题?

2020-07-02 21:54:29 浏览数 (1)

跨域,解决这个问题不单是前端同学的问题,也需要后端的配合,那么后端如何看待跨域问题?还要从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,不如从网关方面入手,个人观点。

0 人点赞