CORS跨域

CORS跨域

1.跨域问题

1.1.什么是跨域

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。

当前页面url 被请求页面url 是否跨域 原因
http://www.test.com/ http://www.test.com/index.html 同源(协议、域名、端口号相同)
http://www.test.com/ https://www.test.com/index.html 跨域 协议不同(http/https)
http://www.test.com/ http://www.baidu.com/ 跨域 主域名不同(test/baidu)
http://www.test.com/ http://blog.test.com/ 跨域 子域名不同(www/blog)
http://www.test.com:8080/ http://www.test.com:7001/ 跨域 端口号不同(8080/7001)

上述表格出自播客:https://blog.csdn.net/qq_38128179/article/details/84956552

比如是从manage.test.com去访问api.test.com,这属于三级域名不同,跨域了。

1.2.为什么有跨域问题?

跨域不一定会有跨域问题。

因为跨域问题是浏览器对于ajax请求的一种安全限制:一个页面发起的ajax请求,只能是于当前页同域名的路径,这能有效的阻止跨站攻击。

因此:跨域问题 是针对ajax的一种限制

但是这却给我们的开发带来了不变,而且在实际生成环境中,肯定会有很多台服务器之间交互,地址和端口都可能不同,怎么办?

1.3.解决跨域问题的方案

浏览器虽然会限制跨域请求,但是也给出了解决方案。如果你确实需要发送跨域的ajax,必须通过被访问的服务端同意才可以。

浏览器与服务器间协商是否允许跨域,这样的方式就是CORS。

参考文档:https://www.ruanyifeng.com/blog/2016/04/cors.html

2.CORS介绍

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。

它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

  • 浏览器端:

    目前,所有浏览器都支持该功能(IE10以下不行)。整个CORS通信过程,都是浏览器自动完成,不需要用户参与。浏览器会在发出ajax时询问服务端是否允许当前网站的跨域请求,并根据服务端响应做出拦截或放行的处理。

  • 服务端:

    CORS通信与AJAX没有任何差别,因此你不需要改变以前的业务逻辑。只不过,浏览器会在请求中携带一些头信息,表明请求者的身份。服务端接收到以后,需要对这些信息做出判断,如果允许则需要在返回的头信息中携带一些许可的声明。

3.SpringCloudGateway的CORS

在SpringCloudGateway中,已经提供了默认的CORS实现,我们只需要通过application.yml做简单配置即可。

spring:
  cloud:
    gateway:
      # 。。。
      globalcors: # 全局的跨域处理
        add-to-simple-url-handler-mapping: true # 是否将当前cors配置加入到SimpleUrlHandlerMapping中,解决options请求被拦截问题
        corsConfigurations:
          '[/**]':
            allowedOrigins: # 允许哪些网站的跨域请求
              - "http://manage.test.com"
              - "http://www.test.com"
            allowedMethods: # 允许的跨域ajax的请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允许在请求中携带的头信息
            allowCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期

完整配置:

server:
  port: 10010
eureka:
  client:
    service-url:
      defaultZone: http://test-registry:10086/eureka
hystrix:
  command:
    default:
      execution.isolation.thread.timeoutInMilliseconds: 6000 # 熔断超时时长:6000ms
ribbon:
  ConnectTimeout: 500 # ribbon链接超时时长
  ReadTimeout: 2000 # ribbon读取超时时长
spring:
  application:
    name: test-gateway
  redis:
    host: test-redis # redis地址
    port: 6379 # redis端口
  cloud:
    gateway:
      default-filters: # 默认过滤项
      - StripPrefix=1 # 去除路由前缀
      - name: Hystrix # 指定过滤工厂名称(可以是任意过滤工厂类型)
        args: # 指定过滤的参数
          name: fallbackcmd  # hystrix的指令名
          fallbackUri: forward:/hystrix/fallback # 失败后的跳转路径
      - name: RequestRateLimiter #请求数限流 名字不能随便写
        args:
          key-resolver: "#{@ipKeyResolver}" # 通过spEL表达式指定一个key生成器,#{}是spEL,@代表spring中的Bean
          redis-rate-limiter.replenishRate: 2 # 生成令牌的速率
          redis-rate-limiter.burstCapacity: 2 # 桶的容量
      globalcors: # 全局的跨域处理
        add-to-simple-url-handler-mapping: true # 是否将当前cors配置加入到SimpleUrlHandlerMapping中,解决options请求被拦截问题
        corsConfigurations:
          '[/**]': # /** 代表拦截一切请求路径,都需要做CORS判断
            allowedOrigins: # 允许哪些网站的跨域请求
            - "http://manage.test.com"
            - "http://www.test.com"
            allowedMethods: # 允许的跨域ajax的请求方式
            - "GET"
            - "POST"
            - "DELETE"
            - "PUT"
            - "OPTIONS"
            allowedHeaders: "*" # 允许在请求中携带的头信息
            allowCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期
      routes:
      - id: item-service # 商品微服务
        uri: lb://item-service
        predicates:
        - Path=/item/**
logging:
  level:
    com.test: debug

你可能感兴趣的:(java)