当一个客户端去访问另一个不同域名或者同域名不同端口的服务时,就会发出跨域请求。如果此时该服务不允许其进行跨域资源访问,那么就会因为跨域问题而导致访问失败。跨源域资源共享CORS(Cross-Origin Resource Sharing)允许Web应用服务器进行跨域访问控制。本文介绍如何在ASM的Virtualservice中配置corsPolicy,实现跨域资源共享。
跨源域资源共享CORS介绍
出于安全性考虑,浏览器会限制页面脚本内发起的跨源HTTP请求,例如在使用XMLHttpRequest和Fetch API遵循同源策略,使用这些API的Web应用程序只能从加载应用程序的同一个域请求HTTP资源,除非响应报文包含了正确CORS响应头。
跨域资源共享CORS是一种基于HTTP头的机制,该机制允许服务器标示除了它自己以外的其它域,协议和端口,使得浏览器可以访问加载这些资源。
- 简单请求模式:
浏览器直接发送跨域请求,并在请求头中携带Origin的头,表明这是一个跨域的请求。服务器端接到请求后,会根据自己的跨域规则,通过Access-Control-Allow-Origin和Access-Control-Allow-Methods响应头,来返回验证结果。
- 预先请求模式:
浏览器会先发送Preflighted requests(预先验证请求),Preflighted requests是一个OPTION请求,用于询问要被跨域访问的服务器,是否允许当前域名下的页面发送跨域的请求。在得到服务器的跨域授权后才能发送真正的HTTP请求。
OPTIONS请求头部中会包含以下头部:Origin、Access-Control-Request-Method、Access-Control-Request-Headers。服务器收到OPTIONS请求后,设置Access-Control-Allow-Origin、Access-Control-Allow-Method、Access-Control-Allow-Headers、Access-Control-Max-Age头部与浏览器沟通来判断是否允许这个请求。如果Preflighted requests验证通过,浏览器才会发送真正的跨域请求。
- 请求方法是下列之一:
GET、HEAD、POST
- 请求头中的Content-Type请求头的值是下列之一:
ext/plain、application/x-www-form-urlencoded、multipart/form-data
- Fetch规范定义了CORS安全头的集合,安全头的集合是下列之一:
Accept、Accept-Language、Content-Language、Content-Type(需要注意额外的限制)
在VirtualService中配置corsPolicy
corsPolicy
字段,使服务允许跨域请求,从而实现跨域通信。apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings-route
spec:
hosts:
- ratings.prod.svc.cluster.local
http:
- route:
- destination:
host: ratings.prod.svc.cluster.local
subset: v1
corsPolicy:
allowOrigins:
- exact: https://example.com
# - regex: * #支持regex
allowMethods:
- POST
- GET
allowCredentials: false
allowHeaders:
- X-Foo-Bar
maxAge: "24h"
参数 | 说明 |
---|---|
allowOrigins | 允许请求服务的来源,允许带哪些Origin地址的请求,支持regex匹配。对于不需要携带身份凭证的请求,服务器可以指定该字段的值为通配符,表示允许来自所有域的请求。 |
allowMethods | 允许请求服务的方法,实际请求所允许使用的HTTP方法。 |
allowHeaders | 允许请求服务的标头,用于预检请求的响应。其指明了实际请求中允许携带的首部字段。 |
exposeHeaders | 公开请求服务的标头,让服务器把允许浏览器访问的头放入白名单。 |
maxAge | 最大浏览器缓存时间,指定了浏览器能够缓存preflight请求结果的时间。 |
allowCredentials | 允许请求服务的凭证,符合要求的凭证才能请求服务。 |