配置跨域资源共享 (CORS)

浏览器默认只允许网页访问同域名资源(同源策略),比如https://www.example.com只能访问相同域名下的内容。OSS属于不同域名,因此浏览器会阻止访问并报跨域错误:image通过为OSS配置跨域资源共享(CORS)规则,可以安全授权指定网站访问OSS资源,让网页直接操作文件。

工作原理

CORS请求分为两种类型:简单请求和预检请求。简单请求可以直接发送,预检请求必须先获得许可才能发送主请求。

如果满足以下任何一种情况,系统将对请求执行预检:

  • 请求使用的是GETHEADPOST以外的方法。

  • 请求使用POST方法且 Content-Type 不是 text/plainapplication/x-www-form-urlencoded 或 multipart/form-data

  • 请求设置了自定义头部,例如x-oss-*

当浏览器向OSS发出简单请求时,会发生以下过程:

  1. 浏览器将Origin头部添加到请求中。Origin头部包含相应资源的来源,例如Origin: https://www.example.com

  2. OSS将请求的HTTP方法以及Origin头部的值与目标BucketCORS配置进行比较,查找匹配项。如果存在匹配项,OSS将在响应中包含Access-Control-Allow-Origin头部。Access-Control-Allow-Origin头部包含初始请求的Origin头部的值。

  3. 浏览器接收响应并检查Access-Control-Allow-Origin值是否与原始请求的域名匹配。如果匹配,则请求成功。如果不匹配,或者响应中不存在 Access-Control-Allow-Origin头部,则请求失败。

预检请求首先执行以下步骤,成功后再执行与简单请求相同的过程:

  1. 浏览器发送一个OPTIONS请求,包含主请求的方法(Access-Control-Request-Method)和头部(Access-Control-Request-Headers)信息

  2. OSS根据CORS配置检查请求的方法和头部是否被允许。如果预检请求中的任何方法或标头值未包含在目标资源允许的方法和标头集合中,请求将失败,并且不会发送主请求。

网站静态资源加载

网站 https://www.example.com 需要加载存放在OSS上的图片、CSSJS文件。

步骤一:配置CORS规则

登录OSS管理控制台,进入目标Bucket数据安全 > 跨域设置,创建规则如下:

参数

配置值

说明

来源

https://www.example.com

只允许来自该特定网站的请求,保障资源安全。

允许Methods

GET,HEAD

GET下载资源,HEAD用于缓存校验。

允许Headers

留空

此场景为简单请求,不触发预检,因此该项配置不会被用到,留空即可。

暴露Headers

ETag,Content-Length

  • ETag: 允许浏览器通过HEAD请求进行缓存校验,若文件未变则返回304 Not Modified,避免重复下载。

  • Content-Length: 可用于在前端显示资源加载进度。

缓存时间

86400

缓存预检结果24小时,减少未来可能产生的预检请求。

返回Vary Origin

不勾选

由于来源是单一且确定的,无需开启此项来处理多域名缓存问题。

步骤二:验证配置

访问https://www.example.com,确认OSS资源(如图片)加载正常,且浏览器控制台无CORS错误。

前端直传文件

用户在网页 https://app.example.com 上,将头像、文档等文件直接上传到OSS。

步骤一:配置CORS规则

登录OSS管理控制台,进入目标Bucket数据安全 > 跨域设置,创建规则如下:

参数

配置值

说明

来源

https://app.example.com

确保只有该授权应用有权限执行上传操作。

允许Methods

PUT, POST

PUTPOST是执行上传操作必需的HTTP方法。

允许Headers

*

前端直传的安全性不依赖固定的Authorization头,而是由有时效性的临时签名 (STS或预签名URL)保障。使用*可兼容SDK携带的多种头部(如x-oss-meta-*),简化配置且无安全风险。

暴露Headers

ETag, x-oss-request-id

  • ETag:是文件上传成功的唯一标识,用于后续校验。

  • x-oss-request-id:若上传失败,前端可捕获此ID,在寻求技术支持时提供,以便快速定位问题。

缓存时间

600

上传操作频率相对较低,缓存10分钟既能减少预检,又能快速响应配置变更。

返回Vary Origin

勾选

为未来可能的多域名部署(如测试环境)做准备,避免CDN缓存污染。

步骤二:验证配置

https://app.example.com页面执行上传操作,确认文件成功上传至OSS,且浏览器控制台无CORS错误。

多环境支持

开发、测试、生产等多个子域名(如dev.example.comapp.example.com)需要访问同一个OSS资源。

步骤一:配置CORS规则

登录OSS管理控制台,进入目标Bucket数据安全 > 跨域设置,创建规则如下:

参数

配置值

说明

来源

https://*.example.com

使用*通配符一次性授权example.com下所有https协议的子域名。

允许Methods

GET,PUT,POST

同时允许资源的读取和上传,满足多环境下的测试需求。

允许Headers

*

多环境开发中,不同环境、不同功能可能引入不同的自定义头部。使用*可以避免频繁修改CORS规则。

暴露Headers

ETag, x-oss-request-id

同时支持下载校验和上传结果反馈。

缓存时间

3600

1小时的缓存时间,在多环境切换和调试时较为灵活。

返回Vary Origin

勾选

必须开启。告知CDN根据Origin头区分缓存,防止多环境间缓存错乱。

步骤二:验证配置

分别在 https://dev.example.com 和 https://app.example.com 上进行访问或上传测试,确认操作均成功。

带认证信息的API式调用

前端应用https://api.example.com需要携带 Authorization 等自定义头部访问受保护的OSS资源。

步骤一:配置CORS规则

登录OSS管理控制台,进入目标Bucket数据安全 > 跨域设置,创建规则如下:

参数

配置值

说明

来源

https://api.example.com

对于携带认证信息的请求,来源必须是精确的、受信任的域名。

允许Methods

GET,PUT,DELETE

支持对私有资源的读取、更新和删除全生命周期管理。

允许Headers

authorization, content-type, x-oss-*

严禁使用*。明确列出所有必要的请求头,遵循最小权限原则,避免泄露不必要的头部信息。

暴露Headers

ETag,x-oss-request-id

提供操作成功后的校验标识和失败后的排错ID

缓存时间

600

对于认证类请求,较短的预检缓存时间(10分钟)有助于更快地应用安全策略变更。

返回Vary Origin

勾选

告知CDN为不同Origin的请求分别缓存,避免混淆。

步骤二:验证配置

https://api.example.com页面发起带Authorization头的请求,确认能成功访问受保护的OSS资源。

应用于生产环境

安全最佳实践

遵循最小权限原则。

  • 精确配置来源(AllowedOrigin):除非 Bucket 是完全公开的,否则严禁将AllowedOrigin设置为*。应精确指定提供服务的网站域名,例如https://www.example.com

  • 收紧允许Methods(AllowedMethod):只开放业务必需的 HTTP 方法。如果网站只需要读取数据,则只配置GETHEAD

  • 具体指定允许Headers(AllowedHeader):对于携带认证信息(如Authorization头)的请求,严禁使用*,必须明确列出所有必要的请求头。

性能最佳实践

  • 优化预检缓存:为 缓存时间 (MaxAgeSeconds) 设置一个合理的值(如 86400 秒,即24小时),可以显著减少预检请求的数量,降低延迟和请求成本。

  • 评估Vary: Origin 的影响:启用 返回 Vary: Origin 虽然可以解决缓存污染问题,但会增加CDN缓存的复杂性,可能导致缓存命中率下降和回源流量增加,从而产生额外成本和延迟。请在评估后使用。

CDN加速场景

如果Bucket开启了CDN加速并使用CDN域名访问,跨域请求将首先到达CDN节点。此时,必须在CDN控制台配置CORS规则,而不是在OSS。OSS侧的CORS配置仅在请求直接访问OSS源站域名时生效。详情请参见CDN跨域资源共享配置

CORS 规则参数说明

每个Bucket最多可以配置20条跨域规则。OSS按照配置的规则顺序,从上到下依次检查,并使用第一条成功匹配的规则。一旦匹配成功,后续规则将不再检查。

参数

是否必须

说明

来源 (AllowedOrigin)

指定哪些网站(来源域)可以跨域访问OSS资源。

  • 格式为协议://域名[:端口],例如https://www.example.com

  • 支持*通配符,但每个来源中最多只能使用一个。

    • 有效示例https://*.example.comhttp://localhost:*

    • 无效示例https://*.example.*https://*

  • 允许多个来源,每行一个。

允许 Methods (AllowedMethod)

指定允许的HTTP方法。

  • 可选值:GET,PUT,POST,DELETE,HEAD

  • 允许多个方法。

允许 Headers (AllowedHeader)

作用于预检请求,决定了实际请求中允许携带的HTTP头部。

  • 支持*通配符,表示允许所有头部。

  • 允许多个Header,每行一个,大小写不敏感。

暴露 Headers (ExposeHeader)

允许前端JavaScript代码可以访问到OSS响应中的哪些头部信息。

  • 不支持*通配符。

  • 允许多个 Header,每行一个。

  • 使用场景:如需在 JS 中获取上传文件的ETagx-oss-request-id,必须在此处添加ETagx-oss-request-id

缓存时间 (MaxAgeSeconds)

指定浏览器缓存OPTIONS预检请求结果的时间(单位:秒)。

  • 作用:在缓存有效期内,对同一资源的相同跨域请求将不再发送预检请求,以优化性能。

返回 Vary: Origin

决定是否在响应中添加Vary: Origin头。此头告知CDN等中间缓存,需根据请求的Origin头来区分缓存版本,以避免多来源访问时的缓存污染问题。

  • 使用场景:当来源配置了多个域名或通配符时,必须开启此项以避免缓存污染。

重要

开启此项可能导致CDN缓存命中率下降。

常见问题

报错No 'Access-Control-Allow-Origin' header is present on the requested resource.

通常是由于浏览器缓存了不带CORS头的旧响应,或者CORS规则配置不当导致请求无法匹配任何规则。

建议先清除浏览器缓存进行测试。如果仍然报错,请参见以下步骤排查CORS跨域规则是否设置正确:

  1. 登录OSS管理控制台

  2. 单击Bucket列表,然后单击目标Bucket名称。

  3. 在左侧导航栏,选择数据安全>跨域设置

  4. 在跨域设置页面,单击创建规则

  5. 创建跨域规则面板,将来源设置为*允许Methods全部勾选,允许Headers设置为*暴露Headers设置为ETagx-oss-request-id缓存时间(秒)设置为0,选中返回Vary: Origin,然后单击确定

  6. 若问题仍然未解决,请任意登录一台服务器,执行以下命令,查看跨域请求头。

    curl -voa '[$URL1]' -H 'Origin:[$URL2]'
    说明
    • [$URL1]为需要请求的OSS资源链接。

    • [$URL2]为您配置跨域规则的来源地址。

    系统显示类似如下。

    • 如果出现返回结果存在一个跨域头且符合您配置的跨域头,可能是由于您第一次请求没有触发跨域,返回的数据被本地缓存;而第二次触发跨域的请求没有请求服务器端,而是直接获取本地的缓存,导致跨域校验失败。 请参考以下解决方法:

      • 在浏览器页面单击Ctrl+F5,清理浏览器缓存,然后在测试跨域问题是否还存在。

      • 您将该OSS资源跨域配置的缓存时间设置为0,避免该资源在客户端进行缓存,每次请求都会重新在服务器端获取鉴权信息。

        说明

        您可以在上传文件时设置文件的cache-controlno-cache,已经上传的文件可以使用ossutil工具进行更改,如何设置cache-control请参见 set-meta(管理文件元数据)

      • 使用CDN加速OSS,这样CDN所有请求都会返回CORS头。

    • 如果返回结果存在两个跨域头或者不符合您在OSS配置的跨域头,可能是由于使用了CDN加速OSS:

      1. 登录CDN控制台,临时取消CDN加速OSS,确认跨域问题不存在。

      2. 确认后,单击具体的域名,依次单击缓存配置 > 节点HTTP响应头

      3. 根据您的实际情况,设定自定义HTTP响应头。

  7. 若跨域问题还是没有解决,请参见OSS跨域资源共享(CORS)出现的常见错误及解决方案进一步排查处理。

报错The 'Access-Control-Allow-Origin' header has a value '...' that is not equal to the supplied origin.

服务器返回了Access-Control-Allow-Origin头,但其值与当前请求的Origin不匹配。这通常是由于缓存问题导致的。当你配置了多个网站域名访问OSS时,浏览器或CDN可能记住了给其他网站的访问许可,然后错误地提供给当前网站使用。

请在CORS规则中开启返回Vary: Origin选项,这样可以避免不同网站间的缓存混乱;或者清除浏览器缓存后重新访问。

报错Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

由于前端代码发送了携带凭证的请求,Access-Control-Allow-CredentialsTrue,但Access-Control-Allow-Origin的值被配置为通配符*,出于安全考虑,不允许使用通配符来源,以防止任意域访问资源并获取Credentials信息(包括Cookies、Authorization Headers等敏感数据)。

  • 如果您需要在请求头中保留Credentials信息,将Access-Control-Allow-Origin的值从通配符*修改为具体的域名(例如:https://example.com)。

  • 如果您不需要在请求头中保留Credentials信息,您可以在前端代码中将xhr.withCredentials设置为false,并确保服务器端的Access-Control-Allow-Credentials设置为false

OSS跨域加载慢如何提升跨域加载时间?

跨域请求实际上是请求Header中携带Origin头请求OSS Bucket中的资源,所以加载快慢不取决于跨域,而是客户端到OSS Bucket的物理链路。如果客户端在中国香港,Bucket是中国内地的,那访问是存在远距离访问的情况,推荐您使用OSS传输加速地址来访问,这样会对链路有加速优化,详情请参见传输加速

说明

传输加速功能可以让全球各地的客户使用优化后的网络来传输数据,极大地提升上传和下载速度,让不同地域的用户都能有很好的访问体验。