CORS

功能说明

cors 插件可以为服务端启用 CORS(Cross-Origin Resource Sharing,跨域资源共享)的返回 HTTP 响应头。

配置字段

名称数据类型填写要求默认值描述
allow_originsarray of string选填允许跨域访问的 Origin,格式为 scheme://host:port ,示例如 http://example.com:8081。当 allow_credentials 为 false 时,可以使用 来表示允许所有 Origin 通过
allow_origin_patternsarray of string选填-允许跨域访问的 Origin 模式匹配, 用 匹配域名或者端口,
比如 http://.example.com — 匹配域名, http://.example.com:[8080,9090] — 匹配域名和指定端口, http://.example.com:[] — 匹配域名和所有端口。单独
表示匹配所有域名和端口
allow_methodsarray of string选填GET, PUT, POST, DELETE, PATCH, OPTIONS允许跨域访问的 Method,比如:GET,POST 等。可以使用 来表示允许所有 Method。
allow_headersarray of string选填DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,
If-Modified-Since,Cache-Control,Content-Type,Authorization
允许跨域访问时请求方携带哪些非 CORS 规范以外的 Header。可以使用 来表示允许任意 Header。
expose_headersarray of string选填-允许跨域访问时响应方携带哪些非 CORS 规范以外的 Header。可以使用 来表示允许任意 Header。
allow_credentialsbool选填false是否允许跨域访问的请求方携带凭据(如 Cookie 等)。根据 CORS 规范,如果设置该选项为 true,在 allow_origins 不能使用 , 替换成使用 allow_origin_patterns *
max_agenumber选填86400秒浏览器缓存 CORS 结果的最大时间,单位为秒。
在这个时间范围内,浏览器会复用上一次的检查结果

注意

  • allow_credentials 是一个很敏感的选项,请谨慎开启。开启之后,allow_credentials 和 allow_origins 为 * 不能同时使用,同时设置时, allow_origins 值为 ”*” 生效。
  • allow_origins 和 allow_origin_patterns 可以同时设置, 先检查 allow_origins 是否匹配,然后再检查 allow_origin_patterns 是否匹配。
  • 非法 CORS 请求, HTTP 状态码返回是 403, 返回体内容为 “Invalid CORS request”。

配置示例

允许所有跨域访问, 不允许请求方携带凭据

  1. allow_origins:
    -
    allow_methods:
    -
    allow_headers:
    -
    expose_headers:
    -
    allow_credentials: false
    max_age: 7200

允许所有跨域访问,同时允许请求方携带凭据

  1. allow_origin_patterns:
    -
    allow_methods:
    -
    allow_headers:
    -
    expose_headers:
    -
    allow_credentials: true
    max_age: 7200

允许特定子域,特定方法,特定请求头跨域访问,同时允许请求方携带凭据

  1. allow_origin_patterns:
    allow_methods:
    - GET
    - PUT
    - POST
    - DELETE
    allow_headers:
    - Token
    - Content-Type
    - Authorization
    expose_headers:
    - ‘*’
    allow_credentials: true
    max_age: 7200

测试

测试配置

  1. apiVersion: networking.higress.io/v1
    kind: McpBridge
    metadata:
    name: mcp-cors-httpbin
    namespace: higress-system
    spec:
    registries:
    - domain: httpbin.org
    name: httpbin
    port: 80
    type: dns
    —-
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
    annotations:
    higress.io/destination: httpbin.dns
    higress.io/upstream-vhost: httpbin.org
    higress.io/backend-protocol: HTTP
    name: ingress-cors-httpbin
    namespace: higress-system
    spec:
    ingressClassName: higress
    rules:
    - host: httpbin.example.com
    http:
    paths:
    - backend:
    resource:
    apiGroup: networking.higress.io
    kind: McpBridge
    name: mcp-cors-httpbin
    path: /
    pathType: Prefix
    —-
    apiVersion: extensions.higress.io/v1alpha1
    kind: WasmPlugin
    metadata:
    name: wasm-cors-httpbin
    namespace: higress-system
    spec:
    defaultConfigDisable: true
    matchRules:
    - config:
    allow_origins:
    allow_origin_patterns:
    allow_methods:
    - GET
    - POST
    - PATCH
    allow_headers:
    - Content-Type
    - Token
    - Authorization
    expose_headers:
    - X-Custom-Header
    - X-Env-UTM
    allow_credentials: true
    max_age: 3600
    configDisable: false
    ingress:
    - ingress-cors-httpbin
    url: oci://higress-registry.cn-hangzhou.cr.aliyuncs.com/plugins/cors:1.0.0
    imagePullPolicy: Always

请求测试

简单请求

  1. curl -v -H Origin: http://httpbin2.example.org:9090“ -H “Host: httpbin.example.com” http://127.0.0.1/anything/get\?foo\=1
  2. < HTTP/1.1 200 OK
    > x-cors-version: 1.0.0
    > access-control-allow-origin: http://httpbin2.example.org:9090
    > access-control-expose-headers: X-Custom-Header,X-Env-UTM
    > access-control-allow-credentials: true

预检请求

  1. curl -v -X OPTIONS -H Origin: http://httpbin2.example.org:9090“ -H “Host: httpbin.example.com” -H “Access-Control-Request-Method: POST” -H “Access-Control-Request-Headers: Content-Type, Token” http://127.0.0.1/anything/get\?foo\=1
  2. < HTTP/1.1 200 OK
    < x-cors-version: 1.0.0
    < access-control-allow-origin: http://httpbin2.example.org:9090
    < access-control-allow-methods: GET,POST,PATCH
    < access-control-allow-headers: Content-Type,Token,Authorization
    < access-control-expose-headers: X-Custom-Header,X-Env-UTM
    < access-control-allow-credentials: true
    < access-control-max-age: 3600
    < date: Tue, 23 May 2023 11:41:28 GMT
    < server: istio-envoy
    < content-length: 0
    <
    Connection #0 to host 127.0.0.1 left intact
    Closing connection 0

非法 CORS Origin 预检请求

  1. curl -v -X OPTIONS -H Origin: http://httpbin2.example.org“ -H “Host: httpbin.example.com” -H “Access-Control-Request-Method: GET” http://127.0.0.1/anything/get\?foo\=1
  2. HTTP/1.1 403 Forbidden
    < content-length: 70
    < content-type: text/plain
    < x-cors-version: 1.0.0
    < date: Tue, 23 May 2023 11:27:01 GMT
    < server: istio-envoy
    <
    * Connection #0 to host 127.0.0.1 left intact
    Invalid CORS request

非法 CORS Method 预检请求

  1. curl -v -X OPTIONS -H Origin: http://httpbin2.example.org:9090“ -H “Host: httpbin.example.com” -H “Access-Control-Request-Method: DELETE” http://127.0.0.1/anything/get\?foo\=1
  2. < HTTP/1.1 403 Forbidden
    < content-length: 49
    < content-type: text/plain
    < x-cors-version: 1.0.0
    < date: Tue, 23 May 2023 11:28:51 GMT
    < server: istio-envoy
    <
    * Connection #0 to host 127.0.0.1 left intact
    Invalid CORS request

非法 CORS Header 预检请求

  1. curl -v -X OPTIONS -H Origin: http://httpbin2.example.org:9090“ -H “Host: httpbin.example.com” -H “Access-Control-Request-Method: GET” -H “Access-Control-Request-Headers: TokenView” http://127.0.0.1/anything/get\?foo\=1
  2. < HTTP/1.1 403 Forbidden
    < content-length: 52
    < content-type: text/plain
    < x-cors-version: 1.0.0
    < date: Tue, 23 May 2023 11:31:03 GMT
    < server: istio-envoy
    <
    * Connection #0 to host 127.0.0.1 left intact
    Invalid CORS request

参考文档