# 为ELB Ingress配置跨域访问
在Web开发中，由于浏览器的同源策略，一个域下的网页通常不能直接请求另一个域下的资源。CORS（跨资源共享，Cross-Origin Resource Sharing）提供了一种安全的方式来绕过这个限制，允许跨域请求。
使用CORS允许跨域访问的场景较多，可能的场景如下：
- 前后端分离：前端应用部署在一个域名下（如 app.example.com），而后端API服务使用另一个域名（如 api.example.com），前端应用在尝试从API服务获取数据时会遇到跨域资源共享问题，需要配置CORS允许跨域访问。
- 第三方服务集成：网站可能需要调用第三方服务（例如地图服务、社交平台登录等）的API接口，则需要配置CORS允许跨域访问。
- 使用内容分发网络CDN：静态资源可能通过CDN提供，而CDN域名与主站域名不同，需要使用跨域访问来加载这些资源。
![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/note_3.0-zh-cn.png)
- ELB Ingress的跨域访问功能依赖ELB能力，使用该功能前请提交工单申请开通ELB跨域访问能力。
- 为ELB Ingress配置跨域访问时，不支持同时设置[URL重定向](https://support.huaweicloud.com/usermanual-cce/cce_10_0690.html)、[Rewrite重写](https://support.huaweicloud.com/usermanual-cce/cce_10_0770.html)、[HTTP重定向到HTTPS](https://support.huaweicloud.com/usermanual-cce/cce_10_0771.html)。
 
#### 前提条件
- 已创建一个CCE Standard或CCE Turbo集群，且集群版本满足以下要求：
  - v1.23集群：v1.23.18-r10及以上
  
  - v1.25集群：v1.25.16-r0及以上
  
  - v1.27集群：v1.27.16-r0及以上
  
  - v1.28集群：v1.28.13-r0及以上
  
  - v1.29集群：v1.29.8-r0及以上
  
  - v1.30集群：v1.30.4-r0及以上
  
  - 其他更高版本的集群
   
- 您需要使用kubectl连接到集群，详情请参见[通过kubectl连接集群](https://support.huaweicloud.com/usermanual-cce/cce_10_0107.html)。
 
#### 约束与限制
- 该特性仅在使用独享型ELB时支持配置。
- 该特性依赖ELB高级转发策略，开启后将不再根据域名/路径匹配确定优先级，请您根据实际需要[自定义转发策略优先级](https://support.huaweicloud.com/usermanual-cce/cce_10_0939.html)。关于转发策略优先级详情请参见[ELB Ingress转发策略优先级说明](https://support.huaweicloud.com/usermanual-cce/cce_10_0950.html)。
 
#### 通过kubectl命令行配置
1. 请参见[通过kubectl连接集群](https://support.huaweicloud.com/usermanual-cce/cce_10_0107.html)，使用kubectl连接集群。
2. 创建名为"**ingress-test.yaml** "的YAML文件，此处文件名可自定义。
   
   ```
   vi ingress-test.yaml
   ```
   以使用已有ELB创建Ingress的场景为例，YAML配置如下：
   ```
   apiVersion: networking.k8s.io/v1
   kind: Ingress 
   metadata:
     name: ingress-test 
     namespace: default 
     annotations:
       kubernetes.io/elb.class: performance # 仅支持独享型ELB
       kubernetes.io/elb.cors-allow-origin: 'http://example.com'  # 允许访问的域
       kubernetes.io/elb.cors-allow-headers: 'fake-header-1' # 允许的请求头
       kubernetes.io/elb.cors-expose-headers: 'fake-header-2' # 需要公开的响应头
       kubernetes.io/elb.cors-allow-methods: 'GET,POST' # 允许的HTTP请求方法
       kubernetes.io/elb.cors-allow-credentials: 'true' # 允许发送凭据
       kubernetes.io/elb.cors-max-age: '3600' # 预检请求的缓存时长
       kubernetes.io/elb.port: '80'
       kubernetes.io/elb.id: 3f5906fb-2b07-4e33-b3fe-b095f03d86a6
   spec:
     rules:
       - host: example.com 
         http:
           paths:
             - path: / 
               backend:
                 service:
                   name: nginx-03657 
                   port:
                     number: 80
               property:
                 ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH 
               pathType: ImplementationSpecific 
     ingressClassName: cce
   ```
   表1跨域访问注解 
   | 参数                                    | 类型             | 描述                                                                                                                                                                                                                                                                                                                                                                                                      | 样例                                   |
   |:---|:---|:---|:---|
   | kubernetes.io/elb.cors-allow-origin   | Array\[string\]  | 指定Access-Control-Allow-Origin响应头的值，表示允许访问的域。 支持以下取值： - 通配符\*：表示允许所有域名访问。  - 配置域名列表：必须为http://或者https://开头的域名，支持填写一级泛域名。格式为"http(s)://example.com"或"http(s)://example.com:port"，端口范围为1\~65535。 最多设置32个值，请以英文逗号分隔。    | ``` kubernetes.io/elb.cors-allow-origin: 'http://example.com' ``` |
   | kubernetes.io/elb.cors-allow-headers  | Array\[string\] | 指定Access-Control-Allow-Headers响应头的值，表示允许的请求头。 单个值只允许包含大小写字母、数字，_和-，且不能以下划线（_）和短划线（-）开头或结尾，最长32个字符。最多设置32个值，请以英文逗号分隔。                                                                                                                                                                                                                                                          | ``` kubernetes.io/elb.cors-allow-headers: 'fake-header-1' ```     |
   | kubernetes.io/elb.cors-expose-headers   | Array\[string\] | 指定Access-Control-Expose-Headers响应头的值，表示可以被跨域请求读取的自定义响应头部，例如通过客户端的JavaScript代码获取非标准响应头字段。 单个值只允许包含大小写字母、数字，_和-，且不能以下划线（_）和短划线（-）开头或结尾，最长32个字符。最多设置32个值，请以英文逗号分隔。                                                                                                                                                                                                             | ``` kubernetes.io/elb.cors-expose-headers: 'fake-header-2' ```    |
   | kubernetes.io/elb.cors-allow-methods   | Array\[string\]  | 指定Access-Control-Allow-Methods响应头的值，表示允许的HTTP请求方法。 可填写多个值，以英文逗号分隔。支持的方法包括：GET，POST、PUT、DELETE、HEAD、OPTIONS、PATCH。                                                                                                                                                                                                                                                            | ``` kubernetes.io/elb.cors-allow-methods: 'GET,POST' ```          |
   | kubernetes.io/elb.cors-allow-credentials | String          | 指定Access-Control-Allow-Credentials响应头的值，表示是否允许发送凭据（如Cookies）。 取值如下： - true：允许发送凭据。  - false：不允许发送凭据。   设置后不允许删除，如需可通过kubernetes.io/elb.cors-disabled删除所有跨域配置。                  | ``` kubernetes.io/elb.cors-allow-credentials: 'true' ```          |
   | kubernetes.io/elb.cors-max-age      | String         | 指定Access-Control-Max-Age响应头的值，表示CORS预检请求的缓存时长。单位：秒。取值范围：**-1** \~**172800**。 该参数值应该根据实际需求合理设置。如果设置得太短，可能会导致频繁的预检请求；如果设置得太长，可能会在CORS策略更新后延迟生效。                                                                                                                                                                                                                               | ``` kubernetes.io/elb.cors-max-age: '3600' ```                    |
   | kubernetes.io/elb.cors-disabled       | String          | 该参数用于关闭所有跨域配置。取值如下： - **true**：关闭所有跨域配置。YAML中的参数值不会被删除，但所有配置均不生效。  - **false**：默认取值，跨域配置将根据用户设置生效。                                                                                                                                            | ``` kubernetes.io/elb.cors-disabled: 'true' ```                   |
      
   
   
3. 创建Ingress。 
   ```
   kubectl create -f ingress-test.yaml
   ```
   回显类似如下，表示Ingress服务已创建。
   ```
   ingress.networking.k8s.io/ingress-test created
   ```
   
   
4. 查看已创建的Ingress。 
   ```
   kubectl get ingress
   ```
   回显如下，表示Ingress服务创建成功。
   ```
   NAME          CLASS    HOSTS          ADDRESS          PORTS   AGE
   ingress-test  cce      example.com    **.**.**.**      80      10s
   ```
   
   
 
#### 验证跨域访问配置是否生效
1. 登录[ELB控制台](https://console.huaweicloud.com/vpc/#/elb/list/grid)，找到Ingress使用的ELB实例，查看监听器的转发策略中是否存在跨域配置。
   ![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000002060065632.png "点击放大")
   
2. 使用curl命令行工具发送跨域请求，并检查响应头部。
   ```
   curl -X OPTIONS -H 'Origin: {源站点}' {Ingress访问URL} -I
   ```
   例如，本示例中源站点为example.com，访问的Ingress URL为121.\*\*.\*\*.\*\*:80，则命令如下：
   ```
   curl -X OPTIONS -H 'Origin: example.com' 121.**.**.**:80 -I
   ```
   回显如下，跨域访问会在原始后端响应中添加Access-Control-\*\*相关的请求头：
   ```
   HTTP/1.1 200 OK 
   Access-Control-Allow-Headers: fake-header-1 
   Access-Control-Expose-Headers: fake-header-2 
   Access-Control-Allow-Methods: GET, POST
   Access-Control-Allow-Credentials: true 
   Access-Control-Max-Age: 3600
   ```
   
 
