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

举报
赵KK日常技术记录 发表于 2023/06/24 12:40:20 2023/06/24
【摘要】 跨域,解决这个问题不单是前端同学的问题,也需要后端的配合,那么后端如何看待跨域问题?还要从jsonp,cors请求等方面入手吗?其实从请求发出开始,跨域应该在请求时解决,但并不是唯一的解决方式。什么是跨域?同源策略:所谓同源是指,域名,协议,端口均相同,只要有一个不同,就是跨域前端解决跨域的方式不等,从后端的角度解决跨域,前段时间写了一段时间的全栈,在请求ajax时并没有用jsonp,项目也...

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

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:

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

请在此添加图片描述

网关过滤

https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gatewayfilter-factories

请在此添加图片描述

可在代码中单独配置

@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,不如从网关方面入手,个人观点。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。