【微服务】CORS跨越问题&网关请求转发时进行路径重写问题

一、跨域 CORS 简述

跨域官方文档: https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS

浏览器跨越问题的英文简写为CORS,其出现问题的截图如下:

【微服务】CORS跨越问题&网关请求转发时进行路径重写问题_第1张图片

浏览器拒绝跨域,是通过同源策略限制的。同源策略是指,发送请求时协议、域名、端口都要相同,其中有一个不同就会产生跨域。

这种需要跨域的请求为非简单请求,在发送这种请求时,会先发送一个预检请求 OPTIONS,对非简单请求的请求流程如下图所示:

【微服务】CORS跨越问题&网关请求转发时进行路径重写问题_第2张图片

当我们使用微服务时,一个服务调用另一个服务的接口,这些服务部署在不同的服务器,不同的端口上,肯定会产生跨域问题。




二、解决跨域:

方法一 :使用 nginx 部署为同一个域 —— nginx 会将请求转化为同一个域

使用 nginx 是非常麻烦的,因此我们使用方法二解决跨域。

方法二: 配置当前请求容许跨域

首先,我们看一下微服务项目的一次前后端交互请求流程:

  1. 前端发请求
  2. 请求到达 GateWay 网关
  3. 网关确认是发给那个微服务后端的请求
  4. 网关转发给相应微服务后端

这样,网关在转发给指定的微服务过程中就产生了跨域。(网关的端口号和指定微服务的端口号不同)

具体解决:

为我们的网关微服务注入如下的过滤器,为所有的请求设置可以跨域,使得允许跨域

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;

@Configuration
public class MallCorsConfiguration {

    UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();


    @Bean
    public CorsWebFilter corsWebFilter(){ // 返回跨域的 Filter
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        // 配置跨越
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.setAllowCredentials(true);
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsWebFilter(urlBasedCorsConfigurationSource);
    }
}




三、路径重写

使用 GateWay 网关提供的 RewritePath 方法进行路径重写,其语法为:

RewritePath=/red/?(?>.*), /$\{segment}

解释:其中 red 为我们不要的路径 ,在逗号后的 /${segment} 之前 加入我们要添加的路径

例子一: 比如 RewritePath=/red/?(?.*), haha /$\{segment} 就表示:

原来为 /red/xxx 的路径 会被重写为 /haha/xxx

例子二: 比如 RewritePath=/red/?(?.*), /$\{segment} 就表示:

原来为 /red/xxx 的路径 会被重写为 /xxx

完整示例如下:
        ## 前端项目放的请求都带有 api 前缀,在后端接收时要把 api 请求去掉,加上指定的前缀
        - id: product_route
          uri: lb://mall-product  # loadbanlance 负载均衡到指定的服务
          predicates:
            - Path=/api/product/** # 指定路径下的请求都放过来
          filters:
            - RewritePath=/api/?(?>.*), /$\{segment} # 路径重写


        - id: admin_route
          uri: lb://renren-fast # loadbanlance 负载均衡到指定的服务
          predicates:
            - Path=/api/**  # 指定路径下的请求都放过来
          filters:
            - RewritePath=/api/?(?>.*), /renren-fast/$\{segment} # 路径重写



你可能感兴趣的:(微服务,微服务,java,架构)