You need to enable JavaScript to run this app.
文档中心
文档控制台
注册
内容分发网络

内容分发网络

复制全文
下载 pdf
使用 CDN 加速 TOS 资源分发
CDN 跨域(CORS)配置的最佳实践
复制全文
下载 pdf
CDN 跨域(CORS)配置的最佳实践

跨域资源共享 (CORS)

跨域资源共享(Cross-Origin Resource Sharing, CORS)是一种浏览器安全机制,用于控制一个源(Origin)的网页应用如何访问另一个源的资源。浏览器默认实行同源策略(Same-Origin Policy),禁止跨源请求。CORS 机制通过在服务器响应中加入特定的 HTTP 头部,授权浏览器执行跨域访问,从而为受控的跨域数据传输提供了安全的通道。

在 CDN 配置跨域资源共享

当您需要允许其他网站的页面访问您托管在 CDN 上的资源时,您需要在 CDN 的 "HTTP 响应头" 特性中进行跨域配置。

"HTTP 响应头" 特性中有一个 跨域校验 选项。该选项用于启用针对 Origin 头部的标准 CORS 校验。

  • 勾选后,CDN 会严格遵循 CORS 规范,根据校验结果动态设置响应头。
    • 校验通过:当请求中的 Origin 在您配置的源列表中时,CDN 会在响应中返回 Access-Control-Allow-Origin 头部,其值等于请求中的 Origin
    • 校验失败:当请求中的 Origin 不在列表中时,响应将不包含 Access-Control-Allow-Origin 头部。
  • 未勾选:CDN 将不执行校验,并始终在响应中设置 Access-Control-Allow-Origin 头部为您配置的完整源列表。此方式不符合 CORS 规范,可能导致预期外的结果。

配置场景

以下是常见的配置场景。

场景一:允许任何网站访问您的资源

如果您的资源是完全公开的,您可以允许来自任何网站的跨域请求。

  1. 登录 CDN 控制台。
  2. 在左侧导航栏,点击 域名管理
  3. 在域名列表页面,找到您要配置的域名,点击 管理
  4. 点击 缓存配置 > HTTP 响应头
  5. 点击 添加,并参考以下说明进行配置:
    • 操作:选择 设置
    • 参数:选择 Access-Control-Allow-Origin
    • 取值:输入 *
    • 跨域校验:无需勾选。当取值为 * 时,响应头固定为 Access-Control-Allow-Origin: *

Image

场景二:允许单个域名的跨域请求

如果您需要允许来自单个域名的访问,请根据您网站使用的协议(HTTP 或 HTTPS)进行配置。如果您的网站同时支持这两种协议,建议将两种协议的域名都添加到允许列表中。以下示例展示了同时配置 HTTP 和 HTTPS 的情况。

  1. 登录 CDN 控制台。
  2. 在左侧导航栏,点击 域名管理
  3. 在域名列表页面,找到您要配置的域名,点击 管理
  4. 点击 缓存配置 > HTTP 响应头
  5. 点击 添加,并参考以下说明进行配置:
    • 操作:选择 设置
    • 参数:选择 Access-Control-Allow-Origin
    • 取值:输入包含 HTTP 和 HTTPS 的域名,例如 http://www.example.com, https://www.example.com
    • 跨域校验:勾选此项。

Image

场景三:允许多个域名的跨域请求

如果您需要允许来自多个不同域名的访问,请根据每个网站使用的协议(HTTP 或 HTTPS)进行配置。以下示例展示了允许来自多个域名(例如 www.example.com 和 docs.example.com)的 HTTPS 访问。

  1. 登录 CDN 控制台。
  2. 在左侧导航栏,点击 域名管理
  3. 在域名列表页面,找到您要配置的域名,点击 管理
  4. 点击 缓存配置 > HTTP 响应头
  5. 点击 添加,并参考以下说明进行配置:
    • 操作:选择 设置
    • 参数:选择 Access-Control-Allow-Origin
    • 取值:输入多个域名,不同域名之间用逗号分隔,例如 https://www.example.com, https://www.example.net
    • 跨域校验:勾选此项。

场景四:允许泛域名访问您的资源

如果您希望授权一个主域名下的所有子域名访问您的资源,您可以使用泛域名的方式。请根据您网站使用的协议(HTTP 或 HTTPS)进行配置。如果您的网站同时支持这两种协议,建议将两种协议的泛域名都添加到允许列表中。以下示例展示了同时配置了 http://*.example.comhttps://*.example.com 的情况。

  1. 登录 CDN 控制台。
  2. 在左侧导航栏,点击 域名管理
  3. 在域名列表页面,找到您要配置的域名,点击 管理
  4. 点击 缓存配置 > HTTP 响应头
  5. 点击 添加,并参考以下说明进行配置:
    • 操作:选择 设置
    • 参数:选择 Access-Control-Allow-Origin
    • 取值:输入允许的泛域名,例如 http://*.example.com, https://*.example.com
    • 跨域校验:勾选此项。

问题排查

如果您在按照本文的说明配置了跨域访问后,仍然遇到请求失败的问题,可以参考以下步骤进行排查。

步骤一:检查跨域配置不生效是否由预检请求导致

如果您已经按照本文的说明完成了 CDN 跨域配置,但请求仍然失败,这很可能是因为浏览器触发了预检请求(Preflight Request)。这是一种针对复杂跨域请求的安全机制,需要您在源站进行额外配置。

说明

预检请求是浏览器自动触发的一种安全机制。如果您不熟悉这个概念,或者不确定它如何影响您的跨域配置,建议您在继续操作前,先阅读 更多信息 中关于预检请求的介绍。理解这个机制可以帮助您更准确地定位问题。

如何处理?

由于 CDN 不会校验预检请求,您必须同时在源站上配置跨域策略来校验预检请求。​以下是几个常见的源站配置示例,示例中的头部值请根据您的实际场景进行修改。

场景一:允许来自任何域名的跨域请求

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization, X-Custom-Header
Access-Control-Max-Age: 3600

场景二:允许来自特定域名的跨域请求

Access-Control-Allow-Origin: https://www.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400

场景三:允许跨域请求携带用户凭证

说明

根据 CORS 规范,当 Access-Control-Allow-Credentialstrue 时,Access-Control-Allow-Origin 不能是 *

Access-Control-Allow-Origin: https://www.example.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 1800
  1. 实际请求 (Actual Request)

只有在收到成功的预检响应后,浏览器才会发送实际的跨域请求。

  • 源站收到实际请求后,处理该请求,并在响应中包含 Access-Control-Allow-Origin 头部(其值应与请求中的 Origin 匹配)。
  • 如果响应中没有 Access-Control-Allow-Origin 头部或其值不匹配,浏览器将阻止页面脚本访问响应内容。

说明

如果您的源站是对象存储(TOS),CDN 控制台的跨域配置(Access-Control-Allow-Origin 响应头)对您不生效。您必须在 TOS 的存储桶中独立配置 CORS 规则。具体方法,请参考 附录:为 TOS 源站配置 CORS 以处理预检请求

步骤二:检查是否需要配置 Vary:Origin

如果您在完成了步骤一的排查后,跨域问题仍然存在,请检查同一用户是否会从多个不同的源(例如 http://a.example.comhttp://b.example.com)请求同一个资源。

在这种情况下,浏览器会缓存第一个源请求到的资源。当第二个源发起请求时,浏览器会直接使用缓存,但此时资源的 Access-Control-Allow-Origin 头部可能与第二个源不匹配,导致跨域失败。

如何处理?

为了解决这个问题,您需要在 CDN 上额外配置 Vary: Origin 响应头。这个头部会告知浏览器,需要根据请求中的 Origin 头部来区分不同源的缓存。

注意

请勿在源站配置 Vary: Origin 响应头,原因请参见 FAQ

  1. 登录 CDN 控制台。
  2. 在左侧导航栏,点击 域名管理
  3. 在域名列表页面,找到您要配置的域名,点击 管理
  4. 点击 缓存配置 > HTTP 响应头
  5. 点击 添加,并参考以下说明进行配置:
    • 操作:选择 设置
    • 参数:选择 Vary
    • 取值:输入 Origin

Image

附录:为 TOS 源站配置 CORS 以处理预检请求

当您的源站是火山引擎对象存储(TOS)时,对于非简单跨域请求,浏览器会首先发送一个预检请求(OPTIONS 请求)。CDN 无法校验预检请求,因此将该请求透传到 TOS。

如果 TOS 返回 403 Forbidden 状态码,表示预检请求未通过校验。导致校验失败的常见原因,是您未在 TOS 存储桶中配置 CORS 规则。浏览器在收到 403 响应后,会中断后续的实际请求。这就导致了即使您在 CDN 控制台为实际请求配置了正确的 Access-Control-Allow-Origin 响应头,浏览器也不会发送实际请求。

因此,您必须在 TOS 的存储桶中配置 CORS 规则,以确保 TOS 能正确校验预检请求。

您需要在存储桶管理页面的左侧导航栏中,点击 权限管理 > 跨域访问设置,然后创建一条 CORS 规则。

场景一:允许来自任何域名的跨域请求

在 CORS 规则中,完成以下配置。

  • 来源 Origin*
  • 操作 MethodsGET, POST, PUT, DELETE(每行一个)
  • Allow-HeadersContent-Type, Authorization, X-Custom-Header(每行一个)
  • 缓存 Max-Age3600

Image

场景二:允许来自特定域名的跨域请求

在 CORS 规则中,完成以下配置。

  • 来源 Originhttp://www.example.comhttps://www.example.com
  • 操作 MethodsGET, POST, PUT, DELETE
  • Allow-HeadersContent-Type, Authorization, X-Custom-Header
  • 缓存 Max-Age3600

FAQ

Q: 建议在 CDN 上配置 Access-Control-Allow-Origin 响应头,为什么不能只在源站上配置?

A: 确实,您可以在源站配置 Access-Control-Allow-Origin 头部。但在使用 CDN 的情况下,这会带来缓存管理的问题。当 CDN 缓存一个文件时,会把源站响应的 Access-Control-Allow-Origin 头部也一并缓存。如果您在源站修改了跨域策略(例如,允许了一个新的域名),CDN 上缓存的旧文件仍然带着过时的头部信息。为了让新策略生效,您必须手动刷新 CDN 上的全部相关缓存,这不仅操作繁琐,还会导致缓存命中率下降,增加回源成本。

而在 CDN 上配置此头部,CDN 会在边缘节点响应请求时,根据您的最新配置动态添加正确的 Access-Control-Allow-Origin 头部,完全避免了因缓存导致的问题,也无需手动刷新。

Q: Vary:Origin 头部有什么作用?为什么在 CDN 配置而不在源站配置?

A: 您应该在 CDN 上配置 Vary: Origin 头部,而不是在源站。原因如下:

  • 如果在源站配置 Vary: Origin:源站会告知 CDN 需要根据请求中的 Origin 头部来区分缓存。这会导致 CDN 对同一个文件缓存多个副本(每个 Origin 对应一个)。当 CDN 收到一个来自新 Origin 的请求时,会因为找不到对应缓存而回源,这会显著降低 CDN 的缓存命中率,增加回源请求的数量和成本。
  • 如果在 CDN 配置 Vary: Origin:CDN 只会缓存一份文件副本。所有来自不同 Origin 的请求都会命中这份缓存。CDN 在响应时,会附带上 Vary: Origin 头部,这个头部是给浏览器看的。它告知浏览器需要根据 Origin 来区分并存储响应,从而避免浏览器端的跨域缓存错误。

因此,将 Vary: Origin 配置在 CDN 侧,既能确保跨域访问的正确性,又能最大化 CDN 的缓存效率。

更多信息

什么是预检请求?

对于一些复杂的跨域请求(即非简单请求),浏览器会先发送一个使用 OPTIONS 方法的预检请求,以确认跨域请求是否被允许。如果预检请求未通过校验,浏览器将不会发送实际的跨域请求。

常见的触发预检请求的场景包括:

  • 请求方法是 PUTDELETEPATCH 等。
  • 请求包含了自定义的 HTTP 头部,例如 AuthorizationX-Custom-Header
  • 请求中的 Content-Typeapplication/json

非简单请求的处理流程

浏览器首先发送一个 OPTIONS 方法的预检请求。这个预检请求包含了实际跨域请求将使用的关键信息:

  • Origin:请求的来源。
  • Access-Control-Request-Method:实际请求将使用的方法(如 PUTDELETE)。
  • Access-Control-Request-Headers:实际请求将包含的自定义头部(如 Authorization)。

CDN 不会校验预检请求,而是将其直接透传回您的源站。当源站收到预检请求时,必须校验请求中的 OriginAccess-Control-Request-MethodAccess-Control-Request-Headers 头部,以判断是否允许该跨域行为。

  • 如果允许,源站的响应需要包含以下头部:

    响应头

    说明

    是否必需

    Access-Control-Allow-Origin

    允许的源(域名),只能包含一个值。

    必需

    Access-Control-Allow-Methods

    允许跨域请求使用的 HTTP 方法。多个值以逗号(,)分隔。

    必需

    Access-Control-Allow-Headers

    允许跨域请求携带的自定义请求头。请求头不区分大小写,多个值以逗号(,)分隔。

    如果预检请求包含 Access-Control-Request-Headers 头,则此响应头为必需。

    Access-Control-Max-Age

    浏览器缓存预检请求响应的时长,单位是秒。

    可选

    Access-Control-Allow-Credentials

    是否允许跨域请求携带用户凭据。取值为 truefalse

    可选

  • 如果不允许,源站不会返回上述 Access-Control-Allow-* 头部。由于响应中未包含这些头部,浏览器会中断跨域请求,并在控制台报告错误。

最近更新时间:2025.12.17 17:59:52
这个页面对您有帮助吗?
有用
有用
无用
无用