• 谷粒商城基础篇47、商品服务API三级分类网关统一配置跨域 整个跨域问题的解决方案经验分享


    1、现在项目有三个工程

    硅谷商城前端工程

    硅谷商城前端对于的后端工程:renren-fast

    以及网关gulimall-gateway

    前端工程访问后端的renren-fast,需要经过网关gulimall-gateway进行路由转发

    即将vue项目里的请求都给网关,网关经过url处理后,去nacos里找到管理后台的微服务,就可以找到对应的端口了,这样我们就无需管理端口,统一交给网关管理端口接口

    在vue前端的工程里面进行下面的设置

    // api接口请求地址
    window.SITE_CONFIG['baseUrl'] = 'http://localhost:88/api';
    // 意思是说本vue项目中要请求的资源url都发给88/api,那么我们就让网关端口为88,然后匹配到/api请求即可,
    // 网关可以通过过滤器处理url后指定给某个微服务
    // renren-fast服务已经注册到了nacos中

    其中http://localhost:88是网关的地址,前端所以的url请求都带上/api这个后缀名称

    通过网关过滤器把api改成renren-fast服务,所以让renren-fast注册到服务注册中心,这样请求88网关转发到8080fast,网关收到/api的请求之后,转发到renren-fast

    所以renren-fast和网关都必须注册到同一个注册中心中,这里使用的是nacos注册中心

    第二步、将fast注册到服务注册中心
    第二步、将fast注册到服务注册中心,这样请求88网关转发到8080fast

    在fast里加入注册中心的依赖

    <!--SpringCloud-nacos 注册中心-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
                <version>2.1.0.RELEASE</version>
            </dependency>
    
            <!--SpringCloud-nacos 配置中心-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
                <version>2.1.0.RELEASE</version>
            </dependency>

    在renren-fast项目中 src/main/resources/application.yml添加nacos配置

    spring:
      application:
        name: renren-fast    # 意思是把renren-fast项目也注册到nacos中(后面不再强调了),这样网关才能转发给
      cloud:
        nacos:
          discovery:
            server-addr: 127.0.0.1:8848 # nacos
            

    然后在fast启动类上加上注解@EnableDiscoveryClient,重启

    @EnableDiscoveryClient
    @SpringBootApplication
    public class RenrenApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(RenrenApplication.class, args);
        }
    
    }

    然后在nacos的服务列表里看到了renren-fast

    问题解决:

    如果报错gson依赖,就导入google的gson依赖

    如果一直获取不到nacos信息, 则在resources路径下创建一个 bootstrap.properties

    spring.application.name=renren-fast
    spring.cloud.nacos.config.server-addr=127.0.0.1:8848

    接下来也就是最为重要的一步:在网关中实现最重要的网关gulimall-gateway,网关路由转发的配置

    第三步、配置**gateway(网关)**模块中的application.yml文件, 添加网关

            - id: admin_route
              uri: lb://renren-fast # 路由给renren-fast (lb)负载均衡
              predicates:  # 什么情况下路由给它
                - Path=/api/**  # 默认前端项目都带上api前缀,就是我们前面题的localhost:88/api
              filters:
                - RewritePath=/api/(?<segment>.*),/renren-fast/$\{segment}  # 把/api/* 改变成 /renren-fast/*fast找

    上面配置的意思就是将

    lb代表负载均衡
    修改过vue的api之后, 此时验证码请求的是 http://localhost:88/api/captcha.jpg?uuid=72b9da67-0130-4d1d-8dda-6bfe4b5f7935

    也就是说, 他请求网关, 路由到了renren-fast , 然后去nacos里找fast.的IP为localhost:8080

    最后拼接后的正确的路径是: localhost:8080/renren-fast/captcha.jpg,网关去路由转发访问localhost:8080/renren-fast/captcha.jpg

    所以要利用网关带路径重写, 参考https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#the-rewritepath-gatewayfilter-factory
    接下来我们再浏览器vue前端工程执行访问

     上面在浏览器输入本地vue前端工程的地址:localhost:8001/#/login,输入用户名和密码的时候,底层会使用http请求向后端发起用户名和密码教研的登录接口

    该接口地址为:/localhost:88/api/sys/login

    这个时候浏览器会报错,浏览器会包跨域安全的问题,当前用户在页面上面输入的地址是localhost:8001/#/login,然后用户要使用浏览器去访问/localhost:88/api/sys/login

    浏览器会对二者的域名、端口、url进行对比,发现不一致就会报跨域问题

    跨域概括
    https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS

    跨域: 指的是浏览器不能执行其他网站的脚本. 它是由浏览器的同源策略造成的, 是浏览器对js施加的安全措施. (ajax可以)
    同源策略: 是指 协议、域名、端口 都要相同, 其中有一个不同都会产生跨域

    URL 说明 是否允许通信
    http://www.a.com/a.js
    http://www.a.com/b.js 同一域名下 允许
    http://www.a.com/lab/a.js
    http://www.a.com/script/b.js 同一域名下不同文件夹 允许
    http://www.a.com:8000/a.js
    http://www.a.com/b.js 同一域名,不同端口 不允许
    http://www.a.com/a.js
    https://www.a.com/b.js 同一域名,不同协议 不允许
    http://www.a.com/a.js
    http://70.32.92.74/b.js 域名和域名对应ip 不允许
    http://www.a.com/a.js
    http://script.a.com/b.js 主域相同,子域不同 不允许
    http://www.a.com/a.js
    http://a.com/b.js 同一域名,不同二级域名(同上) 不允许(cookie这种情况下也不允许访问)
    http://www.cnblogs.com/a.js
    http://www.a.com/b.js 不同域名 不允许

    解决跨域问题的两种办法:

     第一种使用nginx组件,前端vue组件部署在nginx中,后端网关通过nginx进行转发,这样的话浏览器访问前端工程和,发起的login登录请求都在同一个nging域名下面就不会存在跨域的问题

    第二种

    方法二: 配置当次请求允许跨域
    在响应头中添加:参考:https://blog.csdn.net/qq_38128179/article/details/84956552

    Access-Control-Allow-Origin : 支持哪些来源的请求跨域
    Access-Control-Allow-Method : 支持那些方法跨域
    Access-Control-Allow-Credentials :跨域请求默认不包含cookie,设置为true可以包含cookie
    Access-Control-Expose-Headers : 跨域请求暴露的字段
    CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:
    Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma
    如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。
    Access-Control-Max-Age :表明该响应的有效时间为多少秒。在有效时间内,浏览器无须为同一请求再次发起预检请求。请注意,浏览器自身维护了一个最大有效时间,如果该首部字段的值超过了最大有效时间,将失效
    在网关网关统一配置跨域,在网关gulimall-gateway中增加一个filter解决方法:在网关中定义“GulimallCorsConfiguration”类,该类用来做过滤,允许所有的请求跨域。

    package com.hgw.gulimall.gateway.config;
    
    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;
    
    /**
     * Data time:2022/3/14 21:17
     * StudentID:2019112118
     * Author:hgw
     * Description: 配置跨域,该类用来做过滤,允许所有的请求跨域。
     */
    @Configuration
    public class GulimallCorsConfiguration {
    
        @Bean        // 添加过滤器
        public CorsWebFilter corsWebFilter() {
            // 基于url跨域,选择reactive包下的
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    
            // 配置跨域信息
            CorsConfiguration configuration = new CorsConfiguration();
            // 允许跨域的头 *:表示所有
            configuration.addAllowedHeader("*");
            // 允许跨域的请求方式
            configuration.addAllowedMethod("*");
            // 允许跨域的请求来源
            configuration.addAllowedOrigin("*");
            // 是否允许携带cookie跨域
            configuration.setAllowCredentials(true);
    
            // `/**` :任意url都要进行跨域配置
            source.registerCorsConfiguration("/**",configuration);
            return new CorsWebFilter(source);
        }
    }

    开发中推荐第二种,生产上面部署推进使用第一种

  • 相关阅读:
    江西理工大学南昌校区cool code竞赛
    喵哈哈村的魔法考试 Round #3 (Div.2) ABCDE
    项目管理概要记录
    JS开发引用HTML DOM的location和document对象
    Linux下触摸屏驱动程序分析
    敦泰FT6X06单层自容调屏
    FT5X06 如何应用在10寸电容屏(linux-3.5电容屏驱动简析&移植10寸电容屏驱动到Android4.2) (by liukun321咕唧咕唧)
    基于FT5x06嵌入式Linux电容触摸屏驱动
    Linux/Android多点触摸协议
    高通 8x12 添加 TP和按键
  • 原文地址:https://www.cnblogs.com/kebibuluan/p/16471013.html
Copyright © 2020-2023  润新知