
# 为Nginx Ingress配置跨域访问
在Web开发中，由于浏览器的同源策略，一个域下的网页通常不能直接请求另一个域下的资源。CORS（跨资源共享，Cross-Origin Resource Sharing）提供了一种安全的方式来绕过这个限制，允许跨域请求。
使用CORS允许跨域访问的场景较多，可能的场景如下：
- 前后端分离：前端应用部署在一个域名下（如 frontend.example.com），而后端API服务使用另一个域名（如 api.example.com），前端应用在尝试从API服务获取数据时会遇到跨域资源共享问题，需要配置CORS允许跨域访问。
- 第三方服务集成：网站可能需要调用第三方服务（例如地图服务、社交平台登录等）的API接口，则需要配置CORS允许跨域访问。
- 使用内容分发网络CDN：静态资源可能通过CDN提供，而CDN域名与主站域名不同，需要使用跨域访问来加载这些资源。
#### 为Nginx Ingress配置跨域访问示例
本文以一个前端应用程序（frontend.example.com）与后端API服务（api.example.com）通信为例，在Ingress资源的Annotations部分添加指定注解配置跨域访问，注解详情请参见[Enable CORS](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#enable-cors)。
为Nginx Ingress配置跨域访问示例如下：
```
apiVersion: networking.k8s.io/v1 
kind: Ingress 
metadata:
  name: test-ingress 
  namespace: default 
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"     # 启用CORS跨域访问
    nginx.ingress.kubernetes.io/cors-allow-origin: "*"  # 允许访问的域
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, PUT, POST, DELETE, PATCH, OPTIONS"  # 允许的HTTP请求方法
    nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range"  # 允许的请求头
    nginx.ingress.kubernetes.io/cors-expose-headers: "Content-Length,Content-Range"  # 需要公开的响应头
    nginx.ingress.kubernetes.io/cors-max-age: "3600"  # 预检请求的缓存时长
spec:
  rules:
    - host: api.example.com 
      http:
        paths:
          - path: /
            backend:
              service:
                name: example
                port:
                  number: 80
            property:
              ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
            pathType: ImplementationSpecific
  ingressClassName: nginx
```
表1跨域访问配置说明 
| 参数                                                 | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | 配置示例                                                                                                                                         |
|:---|:---|:---|
| nginx.ingress.kubernetes.io/enable-cors            | 启用CORS设置，允许跨域访问。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | ``` nginx.ingress.kubernetes.io/enable-cors: "true" ```                                                                                      |
| nginx.ingress.kubernetes.io/cors-allow-origin      | 指定Access-Control-Allow-Origin响应头的值，表示允许访问的域。 格式为"http(s)://example.com"或"http(s)://example.com:port"，可填写多个值，以英文逗号分隔。 同时支持使用通配符，例如： - "\*"表示允许所有域访问。  - 填写一级泛域名，如"http(s)://\*.example.com"表示允许该域名下的所有子域名访问。   须知： 出于安全考虑，建议指定确切的域名，防止未经授权的域访问敏感资源。 | ``` nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com" ```                                                                 |
| nginx.ingress.kubernetes.io/cors-allow-methods     | 指定Access-Control-Allow-Methods响应头的值，表示允许的HTTP请求方法。 可填写多个值，以英文逗号分隔。                                                                                                                                                                                                                                                                                                                                                                                                                                      | ``` nginx.ingress.kubernetes.io/cors-allow-methods: "GET, PUT, POST, DELETE, PATCH, OPTIONS" ```                                             |
| nginx.ingress.kubernetes.io/cors-allow-headers     | 指定Access-Control-Allow-Headers响应头的值，表示允许的请求头。 可填写多个值，以英文逗号分隔。                                                                                                                                                                                                                                                                                                                                                                                                                                             | ``` nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range" ``` |
| nginx.ingress.kubernetes.io/cors-allow-credentials | 指定Access-Control-Allow-Credentials响应头的值，表示是否允许发送凭据（如Cookies）。 取值如下： - true：允许发送凭据。  - false：不允许发送凭据。   须知： 由于安全策略限制，当Access-Control-Allow-Credentials设置为true时，Access-Control-Allow-Origin不能设置为允许所有域名访问，即不能设为通配符"\*"，防止未经授权的域访问敏感资源，例如携带用户凭证信息的Cookies或者Authorization头部等。       | ``` nginx.ingress.kubernetes.io/cors-allow-credentials: "true" ```                                                                           |
| nginx.ingress.kubernetes.io/cors-expose-headers    | 指定Access-Control-Expose-Headers响应头的值，表示可以被跨域请求读取的自定义响应头部，例如通过客户端的JavaScript代码获取非标准响应头字段。 默认情况下出于安全考虑，浏览器在处理跨域请求时只能访问标准的响应头，包括Cache-Control、Content-Language、Content-Type、Expires、Last-Modified和Pragma。 可填写多个值，以英文逗号分隔。                                                                                                                                                                                                                                                    | ``` nginx.ingress.kubernetes.io/cors-expose-headers: "Content-Length,Content-Range" ```                                                      |
| nginx.ingress.kubernetes.io/cors-max-age           | 指定Access-Control-Max-Age响应头的值，表示CORS预检请求的缓存时长。 该参数值应该根据实际需求合理设置。如果设置得太短，可能会导致频繁的预检请求；如果设置得太长，可能会在CORS策略更新后延迟生效。                                                                                                                                                                                                                                                                                                                                                                                            | ``` nginx.ingress.kubernetes.io/cors-max-age: "3600" ```                                                                                     |
   
#### 验证跨域访问配置是否生效
使用curl命令行工具发送跨域请求，并检查响应头部。
```
curl -X OPTIONS -H 'Origin: {源站点}' {Ingress访问URL} -i
```
例如，本示例中源站点为frontend.example.com，访问的Ingress URL为api.example.com，则命令如下：
```
curl -X OPTIONS -H 'Origin: frontend.example.com' api.example.com -i
```
回显如下，跨域访问会在原始后端响应中添加Access-Control-\*\*相关的请求头：
```
HTTP/1.1 200 OK 
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, PUT, POST, DELETE, PATCH, OPTIONS 
Access-Control-Allow-Headers: DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range 
Access-Control-Expose-Headers: Content-Length,Content-Range 
Access-Control-Allow-Credentials: true 
Content-Type: application/json
```
#### 相关文档
本文中列举了Nginx Ingress中常用的CORS配置，更多详细信息请参考[Enable CORS](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#enable-cors)。
