前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >后端如何解决跨域请求问题?

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

作者头像
疯狂的KK
发布2020-07-02 21:54:29
1.2K0
发布2020-07-02 21:54:29
举报
文章被收录于专栏:Java项目实战Java项目实战

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 赵KK日常技术记录 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
API 网关
腾讯云 API 网关(API Gateway)是腾讯云推出的一种 API 托管服务,能提供 API 的完整生命周期管理,包括创建、维护、发布、运行、下线等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档