• 微服务跨域配置


    有时候,我们需要对所有微服务跨域请求进行处理.

    跨域的说明:
    哪些场景是跨域:不同的系统进行AJAX的请求的时候属于跨域的。 跨域的请求一般是不被允许的。
    1.www.jd.com---->www.taobao.com 跨域
    2.localhost:8001 —>localhost:8002 跨域
    3.www.jd.com:80—>www.jd.com:81 跨域
    4.https —>http 跨域。

    域名相同,端口相同,协议相同 就不是跨域。

    解决跨域的问题的解决方案:

    • CORS的协议 (高版本的浏览器至少 IE10 google)
      • 在服务端进行注解配置(相当配置了CORS的配置项)springmvc的注解 @CrossOrigin
      • 通过在网关(spring cloud gateway)进行统一的配置
      • 通过在网关(nginx里面进行配置CORS)
    • JSONP的方式(了解) 利用JS的漏洞的实现跨域,而且只支持GET请求 不支持其他的请求。

    解决方式涉及到图如下:
    通过@CrossOrigin()注解实现
    在这里插入图片描述
    如果都需要跨域处理,该方式需要在每一个Controller类上配置。

    另外我们一般在SpringCloudGateway网关配置
    在这里插入图片描述
    上图配置信息如下

    spring:
      cloud:
        gateway:
          globalcors:
            cors-configurations:
              '[/**]': # 匹配所有请求
                  allowedOrigins: "*" #跨域处理 允许所有的域
                  allowedMethods: # 支持的方法
                    - GET
                    - POST
                    - PUT
                    - DELETE
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    前端页面通过不同域名或IP访问SpringCloud Gateway,那么,此时直连微服务和网关的跨域问题都解决了,是不是很完美?

    No~ 问题来了,前端仍然会报错:“不允许有多个’Access-Control-Allow-Origin’ CORS头”。

    问题:Vary 和 Access-Control-Allow-Origin 两个头重复了两次,其中浏览器对后者有唯一性限制!

    解决方式之一:手动写一个 CorsResponseHeaderFilter 的 GlobalFilter 去修改Response中的头。

    import org.springframework.cloud.gateway.filter.GatewayFilterChain;
    import org.springframework.cloud.gateway.filter.GlobalFilter;
    import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
    import org.springframework.core.Ordered;
    import org.springframework.http.HttpHeaders;
    import org.springframework.stereotype.Component;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.stream.Collectors;
    
    /**
     * @Auther: 郑洁文
     * @Date: 2022年10月26日 1:10
     * @Description:
     */
    @Component
    public class CorsResponseHeaderFilter implements GlobalFilter, Ordered {
    
    
        private static final String ANY = "*";
    
        @Override
        public int getOrder() {
            // 指定此过滤器位于NettyWriteResponseFilter之后
            // 即待处理完响应体后接着处理响应头
            return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER + 1;
        }
    
        @Override
        @SuppressWarnings("serial")
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                exchange.getResponse().getHeaders().entrySet().stream()
                        .filter(kv -> (kv.getValue() != null && kv.getValue().size() > 1))
                        .filter(kv -> (kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)
                                || kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)
                                || kv.getKey().equals(HttpHeaders.VARY)))
                        .forEach(kv ->
                        {
                            // Vary只需要去重即可
                            if(kv.getKey().equals(HttpHeaders.VARY))
                                kv.setValue(kv.getValue().stream().distinct().collect(Collectors.toList()));
                            else{
                                List<String> value = new ArrayList<>();
                                if(kv.getValue().contains(ANY)){  //如果包含*,则取*
                                    value.add(ANY);
                                    kv.setValue(value);
                                }else{
                                    value.add(kv.getValue().get(0)); // 否则默认取第一个
                                    kv.setValue(value);
                                }
                            }
                        });
            }));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    基于SpringCloudGateway网关配置完成。

  • 相关阅读:
    修改Office2021 默认安装路径
    20240313-设计模式
    elasticsearch bucket 之rare terms聚合
    02-Redis持久化
    如何写出一个成熟的线上线下结合的营销方案?
    面试题 17.09. 第 k 个数(技巧)
    【Linux】进程控制
    MFC-TCP网络编程服务端-Socket
    51单片机1【单片机到底是什么】
    小程序申请,商户号申请,微信支付开通操作流程
  • 原文地址:https://blog.csdn.net/WEN38306482/article/details/127545666