今天在修改天天生鲜超市项目的时候,因为使用了前后端分离模式,前端通过网关统一转发请求到后端服务,但是第一次使用就遇到了问题,比如跨域问题:

但是,其实网关里是有配置跨域的,只是忘了把前端项目的IP和端口号添加到设置里
- server:
- port: 9091
- servlet:
- context-path: /
-
- spring:
- profiles:
- active: dev
- cloud:
- gateway:
- enabled: true
- # 开启自动路由
- discovery:
- locator:
- enabled: true
- routes:
- # fresheveryday
- - id: gateway-fresheveryday
- uri: lb://fresheveryday
- predicates:
- - Path=/api/fresheveryday/**
- filters:
- - StripPrefix=2
-
- httpclient:
- connect-timeout: 1000 # 配置连接超时
- response-timeout: 5s # 配置响应超时
-
- # 跨域配置
- globalcors:
- add-to-simple-url-handler-mapping: true
- cors-configurations:
- '[/**]': #拦截的请求
- maxAge: 36000 #跨域检测的有效期,单位s
- allowedOrigins: #允许跨域的请求
- - "http://localhost:8080" # mhxysy
- - "http://localhost:8081" # layui
- - "http://localhost:8099" # authority
- allowedMethods: #允许跨域的请求方式
- - "GET"
- - "POST"
- allowedHeaders: "*" #允许请求中携带的头信息
- allowedCredentials: true #是否允许携带cookie
-
- logging:
- level:
- springfox: error
- cn.edu.sgu.www.gateway: debug
如上所示,allowedOrigins里设置的是之前使用网关的服务,在nacos控制台修改gateway-dev.yml
添加超市前端项目ttsx的访问地址
- server:
- port: 9091
-
- spring:
- application:
- name: gateway
- cloud:
- # 网关配置
- gateway:
- enabled: true
- # 开启自动路由
- discovery:
- locator:
- enabled: true
- routes:
- # authority
- - id: gateway-authority
- uri: lb://authority
- predicates:
- - Path=/api/authority/**
- filters:
- - StripPrefix=2
-
- # mhxysy
- - id: gateway-mhxysy
- uri: lb://mhxysy
- predicates:
- - Path=/api/mhxysy/**
- filters:
- - StripPrefix=2
-
- # layui
- - id: gateway-layui
- uri: lb://layui
- predicates:
- - Path=/api/layui/**
- filters:
- - StripPrefix=2
-
- # fresheveryday
- - id: gateway-fresheveryday
- uri: lb://fresheveryday
- predicates:
- - Path=/api/fresheveryday/**
- filters:
- - StripPrefix=2
-
- httpclient:
- connect-timeout: 1000 # 配置连接超时
- response-timeout: 5s # 配置响应超时
-
- # 跨域配置
- globalcors:
- add-to-simple-url-handler-mapping: true
- cors-configurations:
- '[/**]': #拦截的请求
- maxAge: 36000 #跨域检测的有效期,单位s
- allowedOrigins: #允许跨域的请求
- - "http://localhost:8080" # mhxysy
- - "http://localhost:8081" # layui
- - "http://localhost:8088" # ttsx
- - "http://localhost:8099" # authority
- allowedMethods: #允许跨域的请求方式
- - "GET"
- - "POST"
- allowedHeaders: "*" #允许请求中携带的头信息
- allowedCredentials: true #是否允许携带cookie
-
- logging:
- file:
- name: D:/log/gateway.log
- level:
- springfox: error
- cn.edu.sgu.www.gateway: debug
添加完之后,重启网关服务gateway,然后再次点登录按钮,还是报错了~

两次请求其实都正常返回响应数据了,状态码为200,这次的错误原因
Multiple CORS header 'Access-Control-Allow-Origin' not allowed
点击右边的问号,原因找到了,服务端返回了两个Access-Control-Allow-Origin响应头,因为网关配置了跨域,后台系统也配置了跨域,所以是gateway和fresheverday的响应头一起返回给了前端。

遇到这个问题应该怎么解决呢?
不要慌,有文档,gateway不是给我们提供了很多过滤器工厂吗,打开官网看一下。
因为博主用的springcloud版本为2.2.6.RELEASE,所以在Spring官网打开的spring cloud gateway的文档页面地址对应的版本处改成2.2.6.RELEASE。
https://docs.spring.io/spring-cloud-gateway/docs/2.2.6.RELEASE/reference/html/#the-deduperesponseheader-gatewayfilter-factory
然后看一下全局过滤器工厂,找到响应头相关的过滤器,如图,很快就找到一个

右边红框内的英文大概意思是会删除两个请求头Access-Control-Allow-Credentials和Access-Control-Allow-Origin重复的值,一旦网关的cors和下游的cors策略都添加了它们。
看到这句英语原话,不由嘴角微动,就是它了,不费吹灰之力。
于是在网关的配置加上上面的配置
- # fresheveryday
- - id: gateway-fresheveryday
- uri: lb://fresheveryday
- predicates:
- - Path=/api/fresheveryday/**
- filters:
- - StripPrefix=2
- - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
重启一下网关服务gateway,点击登录成功跳转到了首页,问题完美解决~

好了,文章就分享到这里了~